详情请点阅读全文
一、概述
- React中的组件: 解决html 标签构建应用的不足。
- 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入。
- 【父子组件】:组件的相互调用中,我们把调用者称为父组件,被调用者称为子组件
二、父子组件传值
父组件给子组件传值方法分为2步:
1、父:在调用子组件的时候定义一个属性:
1
| <Header msg='首页'></Header>
|
2、 子:子组件里面调用:
【说明】父组件还可以把整个父组件传给子组件(此处存疑,新版本可能已失效)
【父】:
1
| <Header home={this}></Header>
|
【子】:
1 2 3
| this.props.home; this.props.home.state.msg; this.props.home.run;
|
1.父组件向子组件传【值】示例——–:
0.【App.js】根组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import React from 'react'; import './App.css'; import Home from './components/Home.js'; import News from './components/news.js';
function App() { return ( <div className="App"> {} <Home /> <hr/> <News /> </div> ); } export default App;
|
1.父1【./components/Home.js】首页组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import React, { Component } from 'react'; import Header from './Header.js';
class Home extends Component { constructor(props){ super(props); this.state={ title:'首页组件' } } render() { return ( <div> <Header title={this.state.title} /> {} </div> ); } } export default Home;
|
3.父2【./components/News.js】新闻组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import React, { Component } from 'react'; import Header from './Header.js';
class News extends Component { constructor(props){ super(props); this.state={ title:'新闻组件' } } render() { return ( <div> <Header title={this.state.title} /> {} </div> ); } } export default News;
|
3.子【./components/Header.js】公共头组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import React, { Component } from 'react';
class Header extends Component { constructor(props){ super(props); this.state={ title:'头部组件' } } render() { return ( <div> <h1>{this.props.title}</h1> {/*2.接收来自父组件传来的title*/} </div> ); } } export default Header;
|
效果:在根组件引入首页、新闻组件效果:
- 首页组件:引用头部组件,并向其传入title:首页组件
- 新闻组件:引用头部组件,并向其传入title:新闻组件
- 达到:用同一个 头部组件,显示自己的头部的目的;
2.父组件向子组件传【方法】示例———-:
【Home.js】:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import React, { Component } from 'react'; import Header from './Header.js';
class Home extends Component { constructor(props){ super(props); this.state={ title:'首页组件' } }
hello=()=>{ alert('这是首页组件的hello方法!') } render() { return ( <div> {} <Header title={this.state.title} hi={this.hello} /> </div> ); } } export default Home;
|
【Header.js】:
注意:此传的Home父组件的方法,只能在此Home父组件,内使用;在如新闻组件内,执行此方法则无效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React, { Component } from 'react';
class Header extends Component { constructor(props){ super(props); this.state={ title:'头部组件' } } render() { return ( <div> <h1>{this.props.title}</h1> {/* 1.在子组件内执行父组件传过来的方法; 2.此处的this.props.xxx 取决于父组件的xxx名,xxx={this.ff} */} <button onClick={this.props.hi}>执行首页组件传过来的hello方法</button> </div> ); } } export default Header;
|
效果:
3.传递整个父组件到子组件【此方法在最新版本无法正确引用可能已取消】
Home.js【方法存疑】
1 2 3 4 5
| hello=()=>{ alert('这是首页组件的hello方法!') } <Header home={this} />
|
Header.js【方法存疑】
1
| <button onClick={this.props.home.hello}>执行首页组件内的方法hello</button>
|
报错:
1 2 3 4 5 6 7 8 9 10 11
| TypeError: Cannot read property 'hello' of undefined Header.render C:/Users/Administrator/Desktop/react/my-app/src/components/Header.js:17 14 | <div> 15 | <h1>{this.props.title}</h1> 16 | {/* 1.在子组件内执行父组件任何部分数据、方法 */} > 17 | <button onClick={this.props.home.hello}>执行首页组件内的方法hello</button> | ^ 18 | 19 | 20 | </div> View compiled
|
父【home.js】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React, { Component } from 'react'; import Header from './Header.js';
class Home extends Component { constructor(props){ super(props); this.state={ title:'首页组件', msg:'首页的消息!' } }
render() { return ( <div> {} <Header home={this.state.msg} /> <h2>这是首页组件的内容</h2> </div> ); } } export default Home;
|
子【header.js】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React, { Component } from 'react';
class Header extends Component { constructor(props){ super(props); this.state={ title:'头部组件' } } render() { return ( <div> <h1>{this.props.title}</h1> {/* 1.在子组件内执行父组件的state.msg。(来自home={this.state.msg}) */} {this.props.home} </div> ); } } export default Header;
|
5.子组件调用父组件的函数,且向其传递消息 (此方法已失效)
home.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import React, { Component } from 'react'; import Header from './Header.js';
class Home extends Component { constructor(props){ super(props); this.state={ title:'首页组件', msg:'首页的消息!' } }
hello=(child_msg)=>{ alert('这是首页组件的hello方法!'+child_msg) } render() { return ( <div> {} <Header title={this.state.title} hello={this.hello} /> <h2>这是首页组件的内容</h2> </div> ); } } export default Home;
|
header.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import React, { Component } from 'react';
class Header extends Component { constructor(props){ super(props); this.state={ title:'头部组件' } } render() { return ( <div> <h1>{this.props.title}</h1> {/* 功能:子组件调用父组件的hello函数,并向其传自己的消息 1.在子组件内[向]父组件传数据[.bind(this,'消息')]; 2.父组件对应的函数要有能接收参数 */} <button onClick={this.props.hello.bind(this,'子组件的消息')}></button> </div> ); } } export default Header;
|
【父子组件传值的应用场景】
- 首先写了一个公共组件:【头部组件】,其它组件都会用到头部这个组件,但会稍有不同;
- 在【首页组件】调用 【头部组件】时,想要它显示成【首页头部组件】
- 在【新闻组件】调用 【头部组件】时,想要它显示成【新闻头部组件】
此时,就可用父组件向子组件传值来解决这个问题,让【头组件】在对应页面显示【xxx头部组件】…
三、父组件主动获取子组件的state数据、函数
- 调用子组件的时候指定ref的值
1
| <Header ref='header'></Header>
|
- 通过this.refs.header 获取整个子组件实例
1.实例:从父组件调用子组件的state数据
Home.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import React, { Component } from 'react'; import Header from './Header.js'; import Footer from './footer.js'
class Home extends Component { constructor(props){ super(props); this.state={ title:'首页组件', msg:'首页的消息!' } }
getfooter=()=>{ alert(this.refs.foo.state.msg); } render() { return ( <div> <Header title={this.state.title} hello={this.hello} /> <h2>这是首页组件的内容</h2>
<hr/> {} <Footer ref='foo' /> {} <button onClick={this.getfooter}>获取底组件的state.msg</button> <br/> </div> ); } } export default Home;
|
footer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import React, { Component } from 'react';
class Footer extends Component { constructor(props){ super(props); this.state={ title:'底部组件', msg:'来自底部组件的state.msg消息' } }
footer_run=()=>{ alert('底部组件函数消息!') } render() { return ( <div> <h3>这是一个底部组件</h3> </div> ); } } export default Footer;
|
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import React from 'react'; import './App.css'; import Home from './components/Home.js'; import News from './components/news.js';
function App() { return ( <div className="App"> <Home /> <hr/> </div> ); } export default App;
|
结果
2.实例:从父组件调用子组件的方法
【home.js】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import React, { Component } from 'react'; import Header from './Header.js'; import Footer from './footer.js'
class Home extends Component { constructor(props){ super(props); this.state={ title:'首页组件', msg:'首页的消息!' } }
getfooter=()=>{ this.refs.foo.footer_run(); } render() { return ( <div> <Header title={this.state.title} hello={this.hello} /> <h2>这是首页组件的内容</h2>
<hr/> {} <Footer ref='foo' /> {} <button onClick={this.getfooter}>获取底组件的footer_run()函数</button> <br/> </div> ); } } export default Home;
|
【footer.js】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import React, { Component } from 'react';
class Footer extends Component { constructor(props){ super(props); this.state={ title:'底部组件', msg:'来自底部组件的state.msg消息' } }
footer_run=()=>{ alert('底部组件footer_run函数的消息!') } render() { return ( <div> <h3>这是一个底部组件</h3> </div> ); } } export default Footer;
|
【app.js】
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from 'react'; import './App.css'; import Home from './components/Home.js'; import News from './components/news.js';
function App() { return ( <div className="App"> <Home /> <hr/> </div> ); } export default App;
|
结果: