本质上来说JSX是React.createElement(component, props, ...children)
方法的语法糖。
所以我们如果使用了JSX,我们其实就是在使用React,所以我们就需要引入React
import React from 'react';
然后我们写组件的时候,自定义组件的首字母是大写的,否则表示它是一个内置组件
看运行时确定类型时,遇到了一个问题,准确来说跟这个小节的内容不是特别有关,就是让我想起了一个内容,就是我们的react组件一般命名都是大写字母开头的,然后我试了一下这样的操作:
function Hello() {
return (
<h1>Hello</h1>
)
}
function World() {
return (
<h1>World</h1>
)
}
const components = {
hello:Hello,
world:World
};
ReactDOM.render(<components.hello/>,document.getElementById('root'));
这样是可以正确渲染出来的,并不会报错,我觉得很奇怪,因为我们写的是<components.hello/>
这样的小写的组件,它为什么不判断为是内置组件呢?我想了一下,也许是因为有.
操作符存在,所以React知道它是一个自定义的组件。如果我们换一种写法:
function Hello() {
return (
<h1>Hello</h1>
)
}
function World() {
return (
<h1>World</h1>
)
}
const components = {
hello:Hello,
world:World
};
const hello = components['hello'];
ReactDOM.render(<hello/>,document.getElementById('root'));
这样写,虽然hello
和上面那个例子的components.hello
完全是等价的,但是React把它识别为一个普通的组件,导致报错。
不得不说React是非常聪明的。
然后回到这一小节(运行时确定类型),就是说我们不能在元素标签的类型中使用表达式,比如:<components.[this.props.type]>
,这么写就是错的,如果我们要实现这种根据参数来改变组件的话,我们需要提前把它赋值给一个大写字母开头的变量,为什么要大写?我们刚说过,如果是小写,那么React就会识别为一个内置组件。最后就是这样:
const SpecificType = components[this.props.type];
return <SpecificType/>
属性的默认值如果我们没有属性赋值,只是写了出来,那么它的默认值是true
。
<MyTextBox autocomplete/>
<MyTextBox autocomplete={true}/>
这里的{true}
不要以为是{true: true}
哈,这个{}
是在JSX中使用JS的标志。
传递属性
如果我们想要把属性对象(不一定真的是传递进来的,也可以是我们加工之后的)传递其他组件,那我们可以这么写。
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
这样确实是非常方便的,省的我们写那些属性名啦,但是这可能让我们把过多的参数传递给某个组件,所以用的时候最好确保所有参数都是有意义的,不然有可能是代码变得混乱,谨慎使用。
子代
这个就是我们之前用到的,但是没有详细解释的一个地方。在开始标签和结束标签之间就是我们的props.children
属性。
如果子代的字符串的话,props.children
是移除两端的空格,中间的换行符是一个空格,内部的多个空格也是一个空格(和HTML一样)。
子代当然也可以是组件啦,我们之前就这么用过,当然,也可以是组件和字符串的结合啦,所以基本上子代可以是任何东西。props.children
是一个数组按顺序包含所有的子代组件。
突然看到
render() {
// 不需要使用额外的元素包裹数组中的元素
return [
// 不要忘记 key :)
<li key="A">First item</li>,
<li key="B">Second item</li>,
<li key="C">Third item</li>,
];
}
包含在数组中的元素渲染出来可以不用元素包裹起来,这个厉害的嘛?我之前一直不知道,不过仔细想想我们之前其实已经用过了,当我们用map
把一个数组转换为组件的时候,返回值就是一个数组嘛,我们也没有把它包在一个组件当中,观察还是不仔细呀。
组件还可以是一个函数哦,我们可以把一些组件的"构造函数"传递进去:),当然用法我目前还了解的不多。
在子代中,有几个情况是不渲染的,我们需要了解一下:
<div />
<div></div>
<div>{false}</div>
<div>{null}</div>
<div>{undefined}</div>
<div>{true}</div>
这个规则也是我们能够使用条件渲染的前提,但也有一些特例,我们需要注意一下,就是数字0
,0
是一个falsy值,但是有时候我们随意使用的话会出现意料之外的事情,比如
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
我们本来是想当messages数组中没有内容的时候我们就不渲染啦,但是这个表达式props.messages.length && ....
的值是0
,React肯定不知道我们是输出0
呢,还是表示false
呢,所以它肯定不能因为0
表示false
,而不去渲染0
,那么我们很多地方其实又需要渲染出0
。所以我们尽量保证我们的逻辑表达式的返回值是布尔类型的返回值。
如果我们需要输出false, null,undefined,true
,我们需要先把它们转换为字符串类型。
<div>
My JavaScript variable is {String(myVariable)}.
</div>
网友评论