一,父传子
在父组件中的子组件标签上属性,在子组件中用this.props.属性接收
父组件:
子组件:
二,子传父
在父组件中的子组件标签上添加属性,属性值为一个函数方法,在子组件中通过this.props.属性传值。
父组件:
子组件:
三,非父子组件传值
方法1:子传父,父再传给子组件 (此方法适用于亲兄弟组件之间的传值,其他的亲戚组件用该方法较为繁琐,不推荐使用)
方法2:封装一个公共的方法,通过发布者-订阅者的模式。
封装common.js
var bus ={
list:[],
// 收集订阅
sub(callback){
this.list.push(callback)
},
// 调函数
pub(val){
this.list.forEach((item)=>{
item && item(val)
})
}
}
export default bus
two组件
import React from "react";
import bus from "./common";
export default class Two extends React.Component{
constructor(){
super();
this.state={
age:15,
sex:'男'
}
}
render(){
return(
<button onClick={()=>{
bus.pub(this.state.sex)
}}>点击2</button>
)
}
}
one组件
import bus from './common'
import React from "react";
import { OneOne } from './OneOne';
export default class One extends React.Component{
constructor(){
super();
this.state ={
num:2,
age:'',
sex:''
}
}
componentDidMount(){
this.init()
}
init(){
bus.sub((val)=>{
this.setState({
sex:val
})
})
}
render(){
return(
<div>
我是one组件你
<OneOne numb={this.state.num} hand={this.handle}/>
我是从oneone子组件传给父组件的年龄:{this.state.age}
我是从兄弟Two组件传过来的性别:{this.state.sex}
</div>
)
}
handle=(val)=>{
this.setState({
age:val
})
}
}
方法3:
react官网提供的context方法(思路是先将其中一个组件修改值传到包裹两个组件state中,另一个要接收数据的组件从包裹它们的组件state中获取(和方法1有点类似)
1,使用react中提供createContext方法
export const Context = React.createContext(null)
2,用Context.Provider标签将两个要传值的非父子组件包裹起来
<Context.Provider value={JSON.stringify(this.state)}>
<div>
<One></One>
<Two changeInfo={this.changeDate} />
</div>
</Context.Provider>
3,用Context.Consumer标签将两个相互传值非父子组件的return包裹起来,注意:包裹标签里是一个函数,并用return将组件内容return出去
此时,两个组件都能获取到包裹她们Context.Provider 标签value的值(注意,不知道是不是版本的原因,我这儿value是不能传对象的 所以我用json.stringify将它转为字符串,然后再接收的组件用json.parse取value值)。
注意此时在two组件修改来自标签value上值时,你会发现控制台打印修改成功后的值,但页面却并未更新,因为你没有通过setState重新让render执行渲染,所以得加一个更改方法去更改包裹她们的组件state中的值
完整代码如下:
father.js
import React from "react";
import One from './one';
import Two from './Two';
export const Context = React.createContext(null)
export default class Father extends React.Component {
constructor(props){
super(props);
this.state={
sex:'女',
}
}
render() {
return (
<Context.Provider value={JSON.stringify(this.state)}>
<div>
<One></One>
<Two changeInfo={this.changeDate} />
</div>
</Context.Provider>
)
}
changeDate=(value)=>{
this.setState({
sex:value
})
}
}
one.js
import bus from './common'
import React from "react";
import { OneOne } from './OneOne';
import {Context} from './Father.js'
export default class One extends React.Component{
constructor(){
super();
this.state ={
num:2,
age:'',
sex:''
}
}
// componentDidMount(){
// this.init()
// }
// init(){
// bus.sub((val)=>{
// this.setState({
// sex:val
// })
// })
// }
render(){
return(
<Context.Consumer>
{(value)=>{
value = JSON.parse(value)
return <div>
我是one组件你
<OneOne numb={this.state.num} hand={this.handle}/>
我是从oneone子组件传给父组件的年龄:{this.state.age}
我是从兄弟Two组件传过来的性别:{value.sex}
</div>
}}
</Context.Consumer>
)
}
handle=(val)=>{
this.setState({
age:val
})
}
}
two组件
import React from "react";
// import bus from "./common";
// import Context from './Father'
import {Context} from './Father.js'
export default class Two extends React.Component{
constructor(){
super();
this.state={
age:15,
sex:'男'
}
}
render(){
return(
<Context.Consumer>
{
(value)=>{
value = JSON.parse(value)
return <button onClick={()=>{
// bus.pub(this.state.sex)
this.props.changeInfo(this.state.sex)
}}>点击2</button>
}
}
</Context.Consumer>
)
}
}
此时就实现了将two组件值通过点击按钮就传给one组件了