前端大杂烩React.js

React中的数据传递----上下文(Context)

2019-01-12  本文已影响2人  w如弈如意c

React如果在整个组件树中传递数据,需要在每一层传递属性(单向数据流,从上往下传递),如果组件套的很深的话,这样传递就非常恶心了。解决这个问题,除了Redux外,你还可以考虑使用强大的”context” API解决这个问题

1.什么时候该使用 Context

官方文档:Context 旨在共享一个组件树内可被视为 “全局” 的数据,例如当前经过身份验证的用户,主题或首选语言等。

2.具体用法

下面是一个简单的上下文使用实例:最外层组件一个color,需要传递给Title组件和Content组件(根组件,绕过子组件,传给孙组件),如下图


页面组件结构如图

基本组件结构如下:

HomePage

class HomePage extends Component { 
    constructor(props) {
        super(props);
        this.state ={
            color: 'red'
        }
    }
    render() {
        return (
            <div>
                <Header />
                <Main />
            </div>
        )
    }
}

Header和Main

class Header extends Component{
    render() {
         return (
             <div>
                 <Title />
             </div>
         )
    }
}

class Main extends Component{
    render() {
         return (
             <div>
                 <Content />
             </div>
         )
    } 
}

Title和Content

class Title extends Component{
   render() {
        return (
            <div>
                这里是标题部分
            </div>
        )
   } 
}

class Content extends Component{
   render() {
        return (
            <div>
                这里是内容部分
            </div>
        )
   } 
}

分一下几步:

static childContextTypes = {
    color: PropTypes.string
}
getChildContext() {
    return {
        color: this.state.color
    }
}
static contextTypes ={
    color: PropTypes.string 
}

这样传递过来,Title和Content就拿到this.context对象,里面包含color属性,则能在Title和Content中使用了

render() {
   return (
       <div  style={{color: this.context.color}}>
           这里是标题部分
       </div>
   )
} 
render() {
    return (
        <div  style={{color: this.context.color}}>
            这里是内容部分
        </div>
    )
}

通过以上,就绕过Header和Main,直接将根节点的属性传递到了孙组件Title和Content里面,这样子组件谁想要谁接收这个属性就行了就行了。

接下来考虑如何在孙组件Header或者Content中去改变这个属性呢?

比如在Content组件, 注意:这个属性是根节点的状态,状态是自能自己改的。所以我们需要在根组件,也就是HomePage定义一个个方法,谁需要改,就把这个方法当属性传给谁。
HomePage:

static childContextTypes = {
    color: PropTypes.string,
    setColor: PropTypes.func
}
getChildContext() {
    return {
        color: this.state.color,
        setColor: this.setColor
    }
}
setColor = (color) => {
    this.setState({color})
}

接下来在需要改变这个属性子组件接受这个方法:并在事件中调用context的方法

static contextTypes ={
    color: PropTypes.string,
    setColor: PropTypes.func
}
render() {
     return (
         <div style={{color: this.context.color}}>
             这里是内容部分
             <button onClick={() => this.context.setColor('green')}>变为绿色</button>
             <button onClick={() => this.context.setColor('yellow')}>变为黄色</button>
         </div>
     )
} 

注意点击事件的写法,确保this指向正确。

代码: https://github.com/wangchao117/react-base-learn/tree/master/src/TodoList10
上一篇 下一篇

猜你喜欢

热点阅读