美文网首页
React入门系列教程(三)创建可复用的组件

React入门系列教程(三)创建可复用的组件

作者: du1dume | 来源:发表于2019-03-07 10:15 被阅读0次

    今天我们来聊聊复用和组合。先看看啥是复用?这是码农专用词汇(也许别的农也用),没啥神秘的,就是重复使用的意思。重复使用啥?重复使用代码啊!一段20行的代码需要重复使用100次,咋整?拷贝粘贴大法是恒古至今不变的真理,然而使用函数是从码农成为码神之路上最重要的利器,没有之一!

    别废话了,直接上代码:

    <div id="rootElement"></div>
    <script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    <script type="text/babel">
        const rootElement = document.getElementById('rootElement')
        
        /*创建一个div,这是一个用jsx写的组件,下面要复用它*/
        const du1dume = <div>du1dume</div>
        
        /*
        1.这里的小括号是为了让代码看起来更有条理,不加也行
        2.container也是一个用jsx写的组件。现在我们要在container组件中复用我们之前创建的du1dume组件。
        3.我们通过之前的文章得知,du1dume在运行时被翻译成js代码,我们又得知,在jsx中使用js代码要用大括号括起来。
        4.为啥在两个du1dume组件外面要再加个div,不加不就是纯js代码了吗?也就不是jsx组件了,好好想想。
        */
        const container = (
            <div className="container">
                {du1dume}
                {du1dume}
            </div>
        )
        
        ReactDOM.render(container, rootElement)
    </script>
    

    我们想改du1dume组件中的文字咋办?总不能再创建一个新文字内容的组件吧,那连码农都当不了了。

    文章开头提到了,复用的关键是函数。函数把要重复使用的代码包裹起来,函数的参数就是要改变的东西,是输入,执行完函数的结果,或者说是输出,就是你最终要的东西。在这里,我们要复用du1dume组件,那么把它包裹进一个函数里,我们想改变文字的内容,那么文字的内容就是这个函数的参数,输出还是这个du1dume组件。还不明白?看代码吧。

    <div id="rootElement"></div>
    <script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    <script type="text/babel">
        const rootElement = document.getElementById('rootElement')
        
        /*
        1.du1dume变成了一个函数,函数的参数是文字内容,执行完函数的结果是jsx组件。这里使用的是箭头函数。
        2.这里的函数参数,我们用的是一个对象,如其名,里面存放的是该jsx组件的属性配置信息。这里用txtContent属性存放了文字内容。
        */
        const du1dume = props => <div>{props.txtContent}</div>
        
        /*
        1.container是jsx组件。
        2.du1dume是个js函数。
        3.在jsx组件中运行js函数,用大括号括起来;传入函数的参数是个对象,对象的txtContent属性存放文字内容,可以动态改变。
        */
        const container = (
            <div className="container">
                {du1dume({txtContent: 'du1dume1'})}
                {du1dume({txtContent: 'du1dume2'})}
            </div>
        )
      
        ReactDOM.render(container, rootElement)
    </script>
    

    接下来我们再看看组合。组合就像俄罗斯套娃,你套我来我套你,最后从小娃变成一个大娃。HTML是个中高手,那么JSX肯定也是如此。现在我们就来想办法把函数变成JSX

    之前提到过const du1dume = <div>du1dume</div>du1dume是个JSX组件,会被Babel翻译为React.createElement方法调用。通过查阅官方文档,我们发现React.createElement方法的第一个参数不仅可以接收一个标签的字符串形式(例如:'div'),还可以接收一个函数作为参数,并且会把props对象传给这个函数,然后这个函数会根据props返回一个新的JSX组件。说起来有点绕,看代码:

    <div id="rootElement"></div>
    <script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    <script type="text/babel">
        const rootElement = document.getElementById('rootElement')
        
        /*注意,这是个函数*/
        const du1dume = props => <div>{props.txtContent}</div>
        
        /*传给createElement方法的第一个参数是一个函数(du1dume),第二个参数会传递给第一个参数,也就是du1dume函数作为参数,名字为props*/
        const container = (
            <div className="container">
                {React.createElement(du1dume, {txtContent: 'du1dume1'})}
                {React.createElement(du1dume, {txtContent: 'du1dume2'})}
            </div>
        )
      
        ReactDOM.render(container, rootElement)
    </script>
    

    既然我们可以用createElement创建组件,就可以转换为JSX的形式。我们来试着做一下:

    <div id="rootElement"></div>
    <script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    <script type="text/babel">
        const rootElement = document.getElementById('rootElement')
        
        /*注意,这是个函数*/
        const du1dume = props => <div>{props.txtContent}</div>
        
        /*传给createElement方法的第一个参数是一个函数(du1dume),第二个参数会传递给第一个参数,也就是du1dume函数作为参数,名字为props*/
        const container = (
            <div className="container">
                <du1dume txtContent="du1dume1" />
                {React.createElement(du1dume, {txtContent: 'du1dume2'})}
            </div>
        )
      
        ReactDOM.render(container, rootElement)
    </script>
    

    我们发现第一个组件没有被渲染出来,看下图1到底发生了什么?

    图1

    原来du1dume被当做字符串而不是函数传递给了createElement方法。再次经过查阅官方文档得知,React对任何以小写字母开头的标签都当做DOM标签,以大写字母开头的标签才当做JSX。让我们再次修改代码:

    <div id="rootElement"></div>
    <script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    <script type="text/babel">
        const rootElement = document.getElementById('rootElement')
        
        /*注意第一个字母大写*/
        const Du1dume = props => <div>{props.txtContent}</div>
        
        const container = (
            <div className="container">
                <Du1dume children="du1dume1" />
                {React.createElement(Du1dume, {txtContent: 'du1dume2'})}
            </div>
        )
      
        ReactDOM.render(container, rootElement)
    </script>
    

    现在,两个组件都正确渲染出来了,现在我们终于可以做套娃了。

    <div id="rootElement"></div>
    <script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    <script type="text/babel">
        const rootElement = document.getElementById('rootElement')
        
        /*注意,这次我们用的是children属性,也就是props里的默认属性之一,这样我们就可以像使用DOM标签一样,在开闭标签之间书写要显示的内容,见下面使用案例。*/
        const Du1dume = props => <div>{props.children}</div>
        
        const container = (
            <div className="container">
                <Du1dume>
                  我是大娃
                  <Du1dume>我是小娃</Du1dume>
                </Du1dume>
            </div>
        )
      
        ReactDOM.render(container, rootElement)
    </script>
    

    相关文章

      网友评论

          本文标题:React入门系列教程(三)创建可复用的组件

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