React Context 的用法

Context是什么
  • 我们知道,在React中数据是通过 props 属性自上而下传递的,而且每次传只能一层;如果在最底层的组件想要获得在最顶层组件传下来的数据或方法,你就得在他们之间的每个组件上通过props层层传递。
    如果有十几层嵌套,我裂开了。。。
  • 幸亏,有了react-redux,我们得救了。稍微深入一点,就会发现他是通过React 中的 Context 结合Redux来实现的
Context怎么用
  • 代码结构
    在这里插入图片描述
  • 渲染视图
    在这里插入图片描述
源码如下
  • index.js
import React from 'react'
import ReactDOM from 'react-dom';

import {MyContext} from './myContext.js'
import Children from './children.js'
import Children02 from './children02.js'

class App extends React.Component {
	constructor(props){
		super(props)
		this.state = {
			data:{
				mydata:'来自App的值'
			}
		}
	}

	handleChange = (v) => {
		this.setState({
			...this.state,
			data:{
				mydata:'更新后的值' + v
			}
		})
	}
  render() {
    return (
	    <div>
			包裹在 Providor 中
			<MyContext.Provider value={this.state} >
					<Children />  
					<Children02 handleChange={this.handleChange}/>  
			</MyContext.Provider>
			<br /><hr />
			不会触发视图更新,React是感知不到数据的变化的,因为他是在myContext.js里一个普通的,并没有被React追踪,只有自己强制更新才行<br/>
			(你可以在dev tool里看到下面两个组件的Context属性同步变化了,但是视图不会更新)
			未包裹在 Providor 中<br/>
			<Children /> 
			<Children02 />  
			<button onClick={() => this.forceUpdate()}>强制更新</button>
			在Providor中包裹的组件和没在包裹之中的组件是会维持各自的数据的,MyContext.Provider相当于充当了里面消费组件的数据源,而没有被包裹的就会使用myContext里面的默认的数据
	    </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));

  • childre.js
    这个组件是通过Children.contextType = MyContext;的形式来消费Providor提供的数据
import React from 'react'
import {MyContext} from './myContext.js';

class Children extends React.Component {
  render() {
    let v = this.context;
    return (
      <div>
      <h2>Children: {v.data.mydata} </h2>
      </div>
    );
  }
}
Children.contextType = MyContext; 

export default Children;
  • children02.js
    这个组件是通过<MyContext.Consumer> {(value) => {//....}} </MyContext.Consumer>的形式来消费Providor提供的数据
import React from 'react'
import {MyContext} from './myContext.js';

class Children02 extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      value: ''
    }
  }

  render() {
    return (
    <MyContext.Consumer>
	    {(v) => (
        <div>
          <h3>Children02:{v.data.mydata}</h3> 
          <input type='input' 
            onChange= { (e) => {
              this.props.handleChange ? 
              this.props.handleChange(e.target.value)
              : v.handleChange(e.target.value)
            }
            }
          >
          </input>
        </div>
      )}
    </MyContext.Consumer>
    );
  }
}
export default Children02;
  • myContext.js
import React from 'react'

const handleChange = (v) => {
	defalutValue.data.mydata = v
}
var defalutValue = {
	data:{
		mydata:'这是默认值(来自myContext.js)'
	},
	handleChange
}

export const MyContext = React.createContext(defalutValue);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值