父组件传递子组件
属性(props)传递
属性(props)传递: 调取子组件的时候,把信息基于属性的方式传递给子组件(子组件Props中存储传递的信息);这种方式只能父组件把信息传递子组件,子组件无法直接的把信息传递给父组件,也就是属性传递(是单向传递的);
父到子(分两步)
父组件要做的事情
1.给父组件调用组件的的地方传参
<Child count={ {n:this.state.n,m:this.state.m} } />
子组件要做的事情
2.子组件需要
1.继承父组件的props属性
constructor(props){
super(props);
console.log(this.props);
}
2. 给需要用的的地方赋值
<div>m的值: { this.props.count.m }</div>
子到父(基于回调函数=>父组件把一个函数传递给子组件,也就是子组件执行了父组件的方法,还可以传递过去一些值,想把父组件的值改成啥就是啥)
父组件做的事
1. 定义一个函数
updateChange = (m)=>{
this.setState({
m: m
})
}
2. 调用子组件的地方传递
<Child
count={ {n:this.state.n,m:this.state.m} }
updateChange={ updateChange }
/>
代码
子组件做的事情
在要改变父组件状态的地方执行父组件传递进来的函数
<button onClick={()=>{
this.props.updateChange(6);
}}>改变m的值</button>
父组件
import React,{ Component } from 'react'
import PropTypes from 'prop-types'
import Child from './Child.js'
export default class parent extends Component{
constructor(){
super();
this.state = {
n : 10,
m : 10
}
}
updateChange = (m)=>{
this.setState({
m: m
})
}
render(){
return(
<div>
<div>n的值: { this.state.n } </div>
<div>m的值: { this.state.m }</div>
<Child
count={ {n:this.state.n,m:this.state.m} }
updateChange={ updateChange }
/>
</div>
)
}
}
子组件
import React,{ Component } from 'react'
import Grandson from './Grandson.js'
export default class Child extends Component{
constructor(props){
super(props);
console.log(this.props);
}
render(){
return(
<div>
<div>n的值: { this.props.count.n } </div>
<div>m的值: { this.props.count.m }</div>
<button onClick={()=>{
this.props.updateChange(6);
}}>改变m的值</button>
<Grandson count={ {n: this.props.count.n ,m:this.props.count.m } } />
</div>
)
}
}
孙组件
import React,{ Component } from 'react'
export default class Grandson extends Component{
constructor(props,context){
super(props,context);
}
render(){
return(
<div>
<div>n的值: { this.props.count.n } </div>
<div>m的值: { this.props.count.m }</div>
</div>
)
}
}
上下文(context)传递
上下文传递: 父组件先把需要给后代元素(包括孙子元素)使用的信息都设置好(设置在上下文中),后代组件需要用到父组件用到中的信息,主动去父组件中调取使用即可.
父到子传参(分三步)
父组件要做的事情
// 1.设置上下文中信息的类型 static childContextTypes = { n: PropTypes.number, m: PropTypes.number }
// 2.获取子组件的上下文 getChildContext(){ // -> return的是啥,相当于给子组件上下文设置成啥. let { n,m } = this.state; return { n, m } }
子组件要做的事情
// 3. 首先类型需要和设置时候的类型一样,否则报错,并且你需要用啥,就写啥即可. static contextTypes = {
n: PropTypes.number,
m: PropTypes.number
}
子到父(基于回调函数=>父组件把一个函数传递给子组件,也就是子组件执行了父组件的方法,还可以传递过去一些值,想把父组件的值改成啥就是啥)
代码
父组件
import React,{ Component } from 'react'
import PropTypes from 'prop-types'
import Child from './Child.js'
export default class parent extends Component{
constructor(props){
super(props);
this.state = {
n : 10,
m : 10
}
}
// 分三步
// 1.设置上下文中信息的类型
static childContextTypes = {
n: PropTypes.number,
m: PropTypes.number,
callback: PropTypes.func
}
// 2.获取子组件的上下文
getChildContext(){
// 只要render重新渲染,就会执行这个方法,重新更新父组件的上下文信息,如果父组件上下文信息更改了,子组件在重新调取的时候,会使用最新的上下文信息(render=>context=>子组件调取渲染);
let { n,m } =this.state
return{
n,
m,
callback
}
}
// 1. 子改变父的定义的函数
updateChange = (n)=> {
this.setState({
n: n
})
}
render(){
return(
<div>
<div>n的值: { this.state.n } </div>
<div>m的值: { this.state.m }</div>
<Child />
</div>
)
}
}
子组件
import React,{ Component } from 'react'
import PropTypes from 'prop-types'
import Grandson from './Grandson.js'
export default class Child extends Component{
constructor(props,context){
super(props,context);
context.n = 1000; // 是可以修改context的值
}
// 3.首先类型需要和设置时候的类型一样,否则报错,并且你需要用啥,就写啥即可.
static contextTypes = {
n: PropTypes.number,
m: PropTypes.number,
callback: PropTypes.func
}
// 给孙组件
/*
static childContextTypes = {
n: PropTypes.number,
m: PropTypes.number,
}
getChildContext(){
// -> return的是啥,相当于给子组件上下文设置成啥.
let { n, m } = this.context
return {
n,
m
}
}
*/
render(){
return(
<div>
<div>n的值: { this.context.n } </div>
<div>m的值: { this.context.m }</div>
{/* 2.子改变父的执行 */}
<button onClick={ ()=>{
let n = this.context.n+1
this.context.callback(n)
}>改变n的值</button>
<Grandson />
</div>
)
}
}
##### 孙组件
```javascript
import React,{ Component } from 'react'
import PropTypes from 'prop-types'
export default class Grandson extends Component{
constructor(props,context){
super(props,context);
console.log(this.context);
}
static contextTypes = {
n: PropTypes.number,
m: PropTypes.number,
}
render(){
return(
<div>
<div>n的值: { this.context.n } </div>
<div>m的值: { this.context.m }</div>
</div>
)
}
}
属性传递和上下文传递的区别
属性传递:
1. 操作起来简单;
2. 子组件被动接收传递的值(组件内的属性是,子组件是不允许修改的(只读的));
3. 只能父传子(子传父不行,父传孙也需要处理,需要子组件处理传递给孙组件).
上下文传递:
1. 操作起来相对复杂一些;
2. 子组件主动接受传递的值(组件内的context(上下文),子组件是可以修改context的值,但是不会影响父组件的值);
3. 一旦设置了父组件的上下文信息,其后代组件都可以拿来用,不需要一层层传递下去.
细节之处,略有疏漏,如有不足或者错误的地方,欢迎大佬批评并加以指正.谢谢.