daily-share
daily-share copied to clipboard
useReducer 和 React.createContext 结合 处理一些多级组件传值 (2020-09-05)
背景: 在实际的开发过程中,我们可能像自组件共享一些props., 但是传递过深的话,需要多次写props ,子组件接受! 写起来非常麻烦! 如果使用以下方式,过程就变得简单起来。
import React, { useContext, useReducer } from 'react'
const Son = () => {
const { name, price ,stock } = useContext(MyContext)
return(
<div style={{ color: 'blue'}}>
<p>这个是子组件的子组件</p>
<ul>
<li>{name}</li>
<li>{price}</li>
<li>{stock}</li>
</ul>
</div>
)
}
const Count = () => {
const { name, price ,stock } = useContext(MyContext)
return (
<div>
<div style={{ color: 'red'}}>
<span>这个是子组件</span>
<ul>
<li>{name}</li>
<li>{price}</li>
<li>{stock}</li>
</ul>
</div>
<Son />
</div>
)
}
/**
* 接口定义
*/
interface IGoodsInfo {
name: string
price: number
stock: number
}
enum IGoodsAction{
set
}
const IGoodsInfo: IGoodsInfo = {
name: '香菇',
price: 12,
stock: 100
}
export const goodsReducer = (state: IGoodsInfo, action: {
type: IGoodsAction,
value: IGoodsInfo
}): IGoodsInfo => {
switch(action.type) {
case IGoodsAction.set :
return action.value
}
}
// :创建一个上下文的容器(组件), defaultValue可以设置共享的默认数据
/**
* 不理解 createContext 可以参考这篇文章:https://www.jianshu.com/p/65b348bf86ad
*/
const MyContext = React.createContext(IGoodsInfo)
const Page3 = () => {
// 使用useReducer
/**
* 不理解useReducer 可以参考这篇文章:https://www.jianshu.com/p/14e429e29798
*/
const [sate, dispatch] = useReducer(goodsReducer, IGoodsInfo)
return (
<div>
<div style={{ color: 'deepPink'}}>
<p>我是父组件</p>
<ul>
<li>{ sate.name }</li>
<li> { sate.price } </li>
<li>{ sate.stock }</li>
</ul>
</div>
<button onClick={() =>{
dispatch({
type: IGoodsAction.set,
value: {
...sate,
price: 1000
}
})
}}>我要在父组件中改变他们</button>
<MyContext.Provider value={sate}>
<Count />
</MyContext.Provider>
</div>
)
}
export default Page3