对前面四篇内容进行简单的回顾:
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/[email protected]/dist/react.min.js"></script> <script src="https://npmcdn.com/[email protected]/dist/react-dom.min.js"></script> <script src="https://npmcdn.com/[email protected]/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/[email protected]/dist/react.min.js"></script> <script src="https://npmcdn.com/[email protected]/dist/react-dom.min.js"></script> <script src="https://npmcdn.com/[email protected]/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/[email protected]/dist/react.min.js"></script> <script src="https://npmcdn.com/[email protected]/dist/react-dom.min.js"></script> <script src="https://npmcdn.com/[email protected]/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/[email protected]/dist/react.min.js"></script> <script src="https://npmcdn.com/[email protected]/dist/react-dom.min.js"></script> <script src="https://npmcdn.com/[email protected]/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