react 深入JSX

作者: 叶绿素yls | 来源:发表于2018-05-26 00:18 被阅读0次

    本质上来说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>
    

    这个规则也是我们能够使用条件渲染的前提,但也有一些特例,我们需要注意一下,就是数字00是一个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>
    

    相关文章

      网友评论

        本文标题:react 深入JSX

        本文链接:https://www.haomeiwen.com/subject/zzbyjftx.html