美文网首页前端大杂烩React.js
React中的数据传递----上下文(Context)

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

作者: w如弈如意c | 来源:发表于2019-01-12 18:10 被阅读2次

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>
        )
   } 
}

分一下几步:

  • 1:在父组件里定义childContextTypes---子上下文类型
static childContextTypes = {
    color: PropTypes.string
}
  • 2:在父组件里定义一个getChildContext用来返回上下文对象,返回的属性要和第一步定义类型对应
getChildContext() {
    return {
        color: this.state.color
    }
}
  • 3:在这些要接收这些上下文对象的组件里定义contextTypes,这里要节后的组件为Title和Content
static contextTypes ={
    color: PropTypes.string 
}

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

  • Title:
render() {
   return (
       <div  style={{color: this.context.color}}>
           这里是标题部分
       </div>
   )
} 
  • Content
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指向正确。

  • 特别注意:上下文必须父子组件间。react-redux里的Provider是通过上下文实现的
代码: https://github.com/wangchao117/react-base-learn/tree/master/src/TodoList10

相关文章

网友评论

    本文标题:React中的数据传递----上下文(Context)

    本文链接:https://www.haomeiwen.com/subject/anecdqtx.html