React.js JSX深入

JSX

基本语法就不再赘述了,下面介绍一些容易出现的坑。

1.节点属性

如果往原生 HTML 元素里传入 HTML 规范里不存在的属性,React 不会显示它们。如果需要使用自定义属性,要加 data- 前缀。
<div data-custom-attribute="foo" />
然而任意属性支持自定义元素
<x-my-component custom-attribute="foo" />

Javascript 表达式

要使用 JavaScript 表达式作为属性值,只需把这个表达式用一对大括号 ( { } ) 包起来,不要用引号 ( ” ” )。
求值表达式本身与JSX没有多大关系,是JS中的特性。它是会返回值的表达式,与语句有本质上的不同,在编写JSX时,在 { } 中不能使用语句(if语句、for语句等等)。我们不能直接使用语句,但可以把语句包裹在函数求值表达式中运用。建议把函数表达式独立出来,在 { } 调用。

1.条件判断的写法

你没法在JSX中使用 if-else 语句,因为 JSX 只是函数调用和对象创建的语法糖。在 { } 中使用,是不合法的JS代码,不过可以采用三元操作表达式

class HelloMessage extends React.Component {
    render() {
        return <div>Hello {this.props.name ? this.props.name : "World"}</div>;
    }
}
ReactDOM.render(
        <HelloMessage />,
    document.getElementById('root')
);

可以使用比较运算符“ || ”来书写,如果左边的值为真,则直接返回左边的值,否则返回右边的值,与if的效果相同。

class HelloMessage extends React.Component {
    render() {
        return <div>Hello {this.props.name || "World"}</div>;}
}
ReactDOM.render(
    <HelloMessage />,
    document.getElementById('root')
);

也可以使用变量来书写

class HelloMessage extends React.Component {
    getName() {
        if (this.props.name)
            return this.props.name
        else
            return "world"
    }
    render() {
        var name = this.getName();
        return <div>Hello {name}</div>;
    }
}

ReactDOM.render(
    <HelloMessage />,
    document.getElementById('root')
);

其中可以把变量去掉,直接在 { } 中调用函数

render() {
    return <div>Hello {this.getName()}</div>;
}

2.函数表达式

// ( )有强制运算的作用
class HelloMessage extends React.Component {
    render() {
        return <div>Hello {
            (function (obj) {
                if (obj.props.name)
                    return obj.props.name
                else
                    return "World"
            }(this))
        }</div>;
    }
}
ReactDOM.render(
    <HelloMessage name={"wzw"} />,
    document.getElementById('root')
);

外括号“ )”放在外面和里面都可以执行。唯一的区别是括号执行完毕拿到的是函数的引用,然后再调用;括号放在外面的时候拿到的事返回值。需传入(this)。

3.注释

JSX 里添加注释很容易;它们只是 JS 表达式而已。你只需要在一个标签的子节点内(非最外层)小心地用 { } 包围要注释的部分

var content = (
  <Nav>
    {/* 一般注释, 用 {} 包围 */}
    <Person
      /* 多
         行
         注释 */
      name={window.isLoggedIn ? window.name : ''} // 行尾注释
    />
  </Nav>
);

4.样式

尽管在大部分场景下我们应该将样式写在独立的CSS文件中,但是有时对于某个特定组件而言,其样式相当简单而且独立,那么也可以将其直接定义在JSX中。在JSX中使用样式和真实的样式也很类似,通过style属性来定义,但和真实DOM不同的是,属性值不能是字符串而必须为对象,需要注意的是属性名同样需要驼峰命名法。例如:

var style = {
    color : "red",
    border : "1px solid #000"
}
class HelloMessage extends React.Component {
    render() {
        return <div>Hello {this.props.name}</div>;
    }
}

ReactDOM.render(
    <div style={style}>
        <HelloMessage name="worldsong"/>
    </div>,
    document.getElementById('root')
);

JSX扩展属性

不要改变props

如果提前就知道了组件的属性的话,写起来很容易。例如component组件有两个动态的属性foo和bar:

var component = <Component foo={x} bar={y} />;

为了解决这个问题,React引入了属性扩展:
当需要拓展我们的属性的时候,定义个一个属性对象,并通过{…props}的方式引入,React会帮我们拷贝到组件的props属性中。重要的是—这个过程是由React操控的,不是手动添赋值的属性。

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />

需要覆盖的时候可以这样写:

var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;

JSX中容易出现的错误:

1style属性

在React中写行内样式时,不能采用引号的书写方式,要这样写:

ReactDOM.render(
    <div style={{color:'red'}}>
        xxxxx
    </div>,
    document.getElementById('root')
);

2.HTML转义


var content='<strong>content</strong>';
ReactDOM.render(
    <div>{content}</div>,
    document.getElementById('root')
);

结果页面直接输出内容了:

《React.js JSX深入》 2.png

React默认会进行HTML的转义,避免XSS攻击,如果要不转义,可以这么写:

var content='<strong>content</strong>';
ReactDOM.render(
    <div dangerouslySetInnerHTML={{__html: content}}></div>,
    document.getElementById('root')
);

3.自定义HTML属性

如果在编写React过程中使用了自定义属性,React不会渲染的
如果需要使用自定义属性,要加 data- 前缀。

4.布尔值、Null 和 Undefined 被忽略

false、null、undefined 和 true 都是有效的子代,但它们不会直接被渲染。下面的表达式是等价的:

<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

这在根据条件来确定是否渲染React元素时非常有用。以下的JSX只会在showHeader为true时渲染<Header />组件。

<div>
  {showHeader && <Header />}
  <Content />
</div>

值得注意的是,JavaScript 中的一些 “falsy” 值(https://developer.mozilla.org/en-US/docs/Glossary/Falsy)(比如数字0),它们依然会被渲染。例如,下面的代码不会像你预期的那样运行,因为当 props.message 为空数组时,它会打印0:

falsy值是在 Boolean 上下文中认定可转换为false的值.

<div>
  {props.messages.length &&
    <MessageList messages={props.messages} />
  }
</div>

要解决这个问题,请确保 && 前面的表达式始终为布尔值:

<div>
  {props.messages.length > 0 &&
    <MessageList messages={props.messages} />
  }
</div>

相反,如果你想让类似 false、true、null 或 undefined 出现在输出中,你必须先把它转换成字符串 相反,如果你想让类似 false、true、null 或 undefined 出现在输出中,你必须先把它转换成字符串

<div>
  My JavaScript variable is {String(myVariable)}.
</div>

!!!React 必须声明

由于 JSX 编译后会调用 React.createElement 方法,所以在你的 JSX 代码中必须首先声明 React 变量。
JSX编译

<div className="red">Children Text</div>;
<MyCounter count={3 + 5} />;

// Here, we set the "scores" attribute below to a JavaScript object.
var gameScores = {
  player1: 2,
  player2: 5
};
<DashboardUnit data-index="2">
  <h1>Scores</h1>
  <Scoreboard className="results" scores={gameScores} />
</DashboardUnit>;

《React.js JSX深入》 3.png

HTML 标签对比 React 组件:

React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。
要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。

var myDivElement = <div className="foo" />;
ReactDOM.render(
    myDivElement   ,
    document.getElementById('root')
);

要渲染 React 组件,只需创建一个大写字母开头的本地变量。

function UserGreeting(props) {
    return <h1>Welcome back!</h1>;
}
var myElement = <UserGreeting someProperty={true} />;
ReactDOM.render(
    myElement   ,
    document.getElementById('root')
);

React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。

!注意:

由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。

    原文作者:香榭的落叶wZw
    原文地址: https://www.jianshu.com/p/a4c3535cd361
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞