这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战
上一篇文章学习了父-子、子-父以及兄弟组件间通过Props以及发布订阅模式的通信,这一篇文章我们来学习其他部分的组件间通信的方法
一、Context
这里写的是新版的Context,新版Context解决了一个问题:旧版Context在修改上下文时,会因为shouldComponentUpdate返回false导致子组件或孙子组件无法正常更新视图。新版则解决了这一个问题。Context避免了手动添加Props,让数据进行层层传递的繁杂问题。Context主要用于很多不同层级的组件间相同数据的使用的场景.
1.Context API的组成
Context有三个重要的组成部分:Context对象、Provider提供者、Consumer消费者,Provider可以将自身的数据提供给Consumer,此外Consumer还能够及时地同步Provider中数据的更新,跨越层级,组件树内皆可Consumer
2.React.createContext
通过使用React.createContext方法可以创建出一个Context对象
const NewContext = React.createContext('New Context');
3.获取Provider和Consumer
在上一步创建出Context对象以后,我们可以从Context对象中获取到Provider和Consumer
const {Provider,Consumer} = NewContext
4.Provider的使用
Provider作为提供者,只需要将Provider作为一个组件,将需要提供的参数保存在一个对象中作为value属性即可共享,并将Provider组件包裹住所需要获取该提供者数据的组件,那么被包裹住的组件均为Consumer
//父组件进行Provider
<Provider value={ {content:this.state.content} }>
<Children />
</Provider>
5.Consumer的使用
//子组件使用Provider中的content
<Consumer>
{
value => {
return <div>{value.content}</div>
}
}
</Consumer>
效果图:
6.总结:Context API使用流程
- 通过
React.createContext创建Context对象,并从Context对象中获取到Provider与Consumer - 确定好需要传递数据的组件,用
Provider在该组件中包裹住子组件,随后将需要传递的数据用对象保存,最后以value属性传给Provider则完成提供数据步骤 - 在子组件中使用
Consumer包裹住即将获取数据的逻辑代码,通过以value为参数的函数进行处理
二、Redux
先来了解一下Redux的描述:Redux是Javascript的状态容器,它提供可预测的状态管理。也就是说,Redux不仅仅适用于React,还适用于Angular、Vue等的状态管理。
1.Redux工作原理
通过下图即可了解Redux的工作原理
2.Reudx的组成部分
Store:可以理解为仓库,用于存储数据Reducer:对变化进行分发与处理,最终将新的数据返回给storeAction:用于对数据变化的描述
View来源于Store,若发生变化,则会进行变化的派发(Action),随后Reducer处理变化,返回新的Store并响应到视图上
工作流如下:在Redux工作过程中,数据流是严格单向的
3.Redux初体验
使用前注意事项:
action需要进行store.dispatch派发dispatch时传入的必须是对象,且必须要有type属性store.subscribe(()=>{})相当于是对store的监听,若store有变化则触发回调
代码如下:
//父组件
render() {
Store.subscribe(()=>{
this.setState({
content:Store.getState().content
})
})
return (
<div>
<div>{this.state.content}</div>
<Children />
<NewChildren />
</div>
)
}
//A组件(Children)
render() {
return (
<div>
<button onClick={ ()=>{ Store.dispatch( { type:"fromA" } ) } }>作为A修改Store</button>
</div>
)
}
//B组件(NewChildren)
render() {
return (
<div>
<button onClick={ ()=>{ Store.dispatch( { type:"fromB" } ) } }>作为B修改Store</button>
</div>
)
}
使用效果如下:
4.使用总结
- 先对
Reducer(state,action)进行定义,定义state的初始状态,以及利用switch判断action.type所处情况编写逻辑,返回对应的新state对象 - 写好
Reducer后,就可以进行Store的创建:const Store = React.createStore(Reducer),并导出创建好的Store - 这个时候就可以在使用
Redux的组件中引入创建好的Store了,在指定事件触发后就可以根据操作进行action的派发(dispatch)了,store.dispatch( {type:""} )(记住,这里传入的对象其实就是action,对action的处理逻辑早就已经写在了Reduce里) - 派发完成以后,
store中的state得到了更新,就可以通过store.getState()来获取state对象。(另外,store.subscribe在store更新时会触发,可以通过这个函数的回调进行组件内状态的更改以便及时更改视图)
简而言之,就是编写逻辑到Reducer、利用Reducer创建Store、利用Store派发触发更新
文字说多了还是有点乱,下面放一张我整理的图,如果有误可以评论我修改一下,感谢。