React中的Context理解和使用------跨多级子组件传属性

React中数据流是自上而下单向流动的,即父组件->子组件->子组件的子组件…,可以通过组件的props属性一级一级地传递和接收。

下面的示例中,MessageList 为父组件,Message 为子组件,Button 为子组件的子组件,通过props一级一级地传递和接收属性:

class Button extends React.Component {
  render() {
    return (
      <button style={{background: this.props.color}}>
        {this.props.children}
      </button>
    );
  }
}

class Message extends React.Component {
  render() {
    return (
      <div>
        {this.props.text} <Button color={this.props.color}>Delete</Button>
      </div>
    );
  }
}

class MessageList extends React.Component {
  render() {
    const color = "purple";
    const children = this.props.messages.map((message) =>
      <Message text={message.text} color={color} />
    );
    return <div>{children}</div>;
  }
}

我们注意到,在子组件Message 中并没用用到父组件MessageList 传递过来的color属性,而是立即将该属性传给他的Button 子组件,那么,我们是否可以不通过中间的组件Message ,而直接从父组件MessageList 将属性传递给组件Button 呢?

context

全局空间:父组件设置context并放入某状态,其下每个孩子组件都可以从其取得状态,而不用一层一层的向下传递。
注意:父组件的父组件是无法访问到context中存放的状态的。

语法:

static childContextTypes = {
  <key>: PropTypes.<类型>
}

getChildContext () {
  return {
    <key>: <value>
  }
}

childContextTypes:是为context中的字段设置类型检查,必须设置
getChildContext():用来设置组件的context
子组件要使用:

//contextTypes首先要类型检查,必须的
class Title extends Component {
  static contextTypes = {
    themeColor: PropTypes.string
  }

//this.context.<key>即可获取
render () {
    return (
      <h1 style={{ color: this.context.themeColor }}>React</h1>
    )
  }

示例:

class Button extends React.Component {
  render() {
    return (
      <button style={{background: this.context.color}}>
        {this.props.children}
      </button>
    );
  }
}

Button.contextTypes = {
  color: React.PropTypes.string
};

class Message extends React.Component {
  render() {
    return (
      <div>
        {this.props.text} <Button>Delete</Button>
      </div>
    );
  }
}

class MessageList extends React.Component {
  getChildContext() {
    return {color: "purple"};
  }

  render() {
    const children = this.props.messages.map((message) =>
      <Message text={message.text} />
    );
    return <div>{children}</div>;
  }
}

MessageList.childContextTypes = {
  color: React.PropTypes.string
};

分析:

  • 在父组件MessageList中,通过childContextTypes定义了该组件的context对象:只有一个属性color,且必须是字符串
  • 然后通过getChildText方法对context对象的属性赋值:color的值为purple
  • 父组件的context对象完成
  • 在第二级子组件Button中通过contextTypes申明接受到的context对象:只有一个属性color,且必须是字符串
  • 然后通过this.context.color使用context对象中的属性

这样就实现了跨级传递属性。

这种方式有一个很大的缺点就是子组件可以随意得修改context对象的属性值,因为context类似一个全局变量,当组件层级多的时候就很容易出现混乱,因此不推荐使用这种方式传递属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值