首页 > 代码库 > react入门(5)

react入门(5)

对前面四篇内容进行简单的回顾:

react入门(1):jsx,组件,css写法

react入门(2):事件,this.props.children,props,...other

react入门(3):jsx/html/css分开写(分成三个文件),state,onChange事件,refs

react入门(4):props和state的混搭使用,state与props的对比,生命周期(挂载、更新、移除)

 

今天要讲的是组件之间的通信,会结合前面学的一些内容,主要以实例为主来进行讲解。

 

一、父组件向子组件传递信息

 来看一个例子

案例1:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        .box{background:red;}
    </style>
    <meta charset="utf-8">
    <script src="https://npmcdn.com/react@15.3.1/dist/react.min.js"></script>
    <script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.min.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <script type="text/babel">
        // 父组件
        var Parent = React.createClass({
            getInitialState: function () {
                return {
                    checked: true,
                    class:box
                };
            },
              render: function() {
                return (
                      <Child txt="是否喜欢咖啡" class={this.state.class} checked={this.state.checked} />
                );
              }
        });
        
        // 子组件
        var Child = React.createClass({
              render: function () {
                var checked = this.props.checked;
                   return (
                    <div className = {this.props.class}>
                        {this.props.txt}: 
                        <input type="checkbox" checked={checked} />
                    </div>
                );
              }
        });
        
        ReactDOM.render(
            <Parent />,
            document.getElementById(example)
        )
      
    </script>
</body>
</html>

 效果图如下

技术分享

下面来分析一下

  • 父元素Parent上在getInitialState里设置了两个初始值checked和class

技术分享

  • 父元素Parent的Child标签上有三个属性txt、class、checked。txt的属性值为“是否喜欢咖啡”;class的属性值是从getInitialState里获取的class的初始值,值为box;checked的属性值是从getInitialState里获取的checked的初始值,值为true。

技术分享

  • 子组件Child的checked这个变量的值,是从父组件Parent传递过来的,即为父组件Parent的Child标签上checked的属性值,即为true。

技术分享

  • 子组件Child的className的属性值,是从父组件Parent传递过来的,即为父组件Parent的Child标签上class的属性值,即为box。

技术分享

  • 子组件this.props.txt,是从父组件Parent传递过来的,即为父组件Parent的Child标签上txt的属性值,即为“是否喜欢咖啡”。

 技术分享

 

上面这个例子是父组件里面嵌套了一个子组件,当然我们子组件里面还可以嵌套孙子组件,下面来看一个简单的案例

案例2:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <meta charset="utf-8">
    <script src="https://npmcdn.com/react@15.3.1/dist/react.min.js"></script>
    <script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.min.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <script type="text/babel">
        // 父组件
        var Parent = React.createClass({
            getInitialState: function () {
                return {
                    checked: true,
                };
            },
            render: function() {
              return (
                   <Child txt="是否喜欢咖啡" checked={this.state.checked} />
              );
            }    
        });
        
        // 子组件
        var Child = React.createClass({
              render: function () {
                   return (
                    <div>
                        <Grandchild txt={this.props.txt} />
                        <input type="checkbox" checked={this.props.checked} />
                    </div>
                );
              }
        });
        
        // 孙子组件
        var Grandchild = React.createClass({
              render: function () {
                   return (
                    <label>
                        {this.props.txt}
                    </label>
                );
              }
        });
        ReactDOM.render(
            <Parent />,
            document.getElementById(example)
        )
      
    </script>
</body>
</html>

 效果如下

技术分享

下面来分析一下(还是直接图片上面注释来分析)

技术分享

技术分享

 技术分享

从这个例子我们可以知道,信息可以从Parent一直传递到Grandchild上去,以此类推可以依次传递下去。但是,如果组件嵌套层次太深,那么从外到内组件的交流成本就变得很高,通过 props 传递值的优势就不那么明显了。

 

二、子组件向父组件传值

案例3:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <meta charset="utf-8">
    <script src="https://npmcdn.com/react@15.3.1/dist/react.min.js"></script>
    <script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.min.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <script type="text/babel">
        // 父组件
        var Parent = React.createClass({
              getInitialState: function () {
                return {
                      txt: 123
                };
              },
              childChange: function (newState) {
                this.setState({
                      txt: newState
                });
             },
              render: function() {
                return (
                      <div>
                        {this.state.txt}
                        <Child tab="输入框" txt={this.state.txt} callback={this.childChange} />
                      </div>
                );
              }
        });

        // 子组件
        var Child = React.createClass({
              getInitialState: function () {
                return {
                  txt: this.props.txt
                };
              },
              toChange: function (event) {
                var newState = event.target.value;
                this.setState({
                      txt: newState
                });
                this.props.callback(newState);
              },
              render: function () {
                return (
                    <div>
                        <span>{this.props.tab}</span>
                        <input type="text" value={this.state.txt} onChange={this.toChange} />
                    </div>
                );
              }
        });

        ReactDOM.render(
            <Parent />,
            document.getElementById(example)
        )
      
    </script>
</body>
</html>

效果如下

技术分享 

下面来分析一下(结合下面有注释的图来看)

  • 父组件Parent的Child标签上txt属性的值,是从getInitialState里设置的txt的值,即为123
  • 子组件Child的span标签里{this.props.tab},是获取的父元素Parent里传递过来的信息,即为父元素Parent的Child标签上tab属性的值,即为“输入框”。
  • 子组件Child的input标签上value的值,是从getInitialState里设置的txt的值,这个txt的值为父元素Parent的Child标签上txt属性的值,即为123。
  • 在子组件Child里,当input值发生改变的时候,就触发onChange事件,调用toChange方法。
  • 在子组件Child的toChange方法里,event.target.value是input的value值,将input的value值赋值给newState这个变量;通过setState将txt的值修改为newState的值,即为input的value值;this.props.callback,这里向父元素的callback里传递了一个newState值,即为input的value值。
  • 在父组件Parent的Child标签上,callback被触发后,会调用childChange方法,在这个方法里,通过setState将txt的值修改为子组件Child传递过来的newState值。

技术分享

技术分享

 

 三、没有嵌套关系的组件之间传值

 案例4:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <meta charset="utf-8">
    <script src="https://npmcdn.com/react@15.3.1/dist/react.min.js"></script>
    <script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.min.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <script type="text/babel">
        var Parent = React.createClass({
            getInitialState: function() {
                return {
                      txt: 123
                };
            },
            childOneCb:function(newOne){
                this.setState({
                    txt:newOne
                })
            },
            render: function () {
              return (
                <div>
                  <ChildOne txt={this.state.txt} cbOne={this.childOneCb} />
                  <ChildTwo txt={this.state.txt} />
                </div>
              );
            }
        });

        var ChildOne = React.createClass({
            getInitialState: function() {
                return {
                      txt: this.props.txt
                };
            },
            inputChange:function(event){
                this.setState({
                    txt:event.target.value
                });
                this.props.cbOne(event.target.value);
            },
              render: function() {
                return (
                      <div>
                          ChildOne:<input type="text" value={this.state.txt} onChange={this.inputChange} />
                      </div>
                );
              }
        });

        var ChildTwo = React.createClass({
              render: function () {
                return (
                      <div>
                          ChildTwo:{this.props.txt}
                      </div>
                );
              }
        });

        ReactDOM.render(
            <Parent />,
            document.getElementById(example)
        )
      
    </script>
</body>
</html>

效果如下

 技术分享

下面来分析一下

  • 首先来看父元素Parent

技术分享

技术分享

  • 接下来看ChildOne

技术分享

技术分享

技术分享

cbOne在父组件Parent上ChildOne标签上看到

  • 接下来再回到父组件Parent上

技术分享

技术分享

这个时候已经完成了在子组件ChildOne上修改input的value值,父组件Parent里txt的状态会随之改变

  • 下面来看ChildTwo

技术分享

父组件Parent里txt值随着子组件ChildOne里input值而改变,这里的值也是获取的父组件Parent里txt的状态。因此ChildTwo里的值也会随着ChildOne里的值而改变。

 

 

╮(╯▽╰)╭感觉这几个例子讲的有点乱~~~将就看看吧,有错误或者疑惑的地方可以给我留言。

入门的部分就讲这么多啦,后面再总结的一些东西都要结合手脚架工具了,下面推荐几个东西大家可以看一下:

reactjs、react router、redux、antd

 

react入门(5)