持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
继上文,当使用provider传递多个值时包裹的样子正所谓是“狼狈不堪”
<ColorContext.Consumer>
{
(theme) => {
return (
<FontContext.Consumer>
{
(font) => {
return(
<div >
<p>theme1 color :{theme}</p>
<p>theme1 font :{font}</p>
<Child3 />
<Child4 />
</div>
)
}
}
</FontContext.Consumer>
)
}
}
</ColorContext.Consumer>
于是开始想解决办法
- 一、使用useContext直接拿到value值
function Child1(){
//直接拿到ColorContext与FontContext的初始数据
const theme = useContext(ColorContext)
const font = useContext(FontContext)
return(
<div>
//直接可以使用
<p>theme1 color :{theme}</p>
<p>theme1 font :{font}</p>
<Child3 />
<Child4 />
</div>
)
}
- 将多个数据整合在一个对象中
const ThemeContext = createContext()
设置一个对象,在根组件中为子组件传值:
const [theme , setTheme] = useState({color:"red",font:"bold"})
把主题传递给子组件
<ThemeContext.Provider value={theme}>
<Child1 />
</ThemeContext.Provider>
在子组件中使用useContext接收对象,并展示数据
function Child1(){
const theme = useContext(ThemeContext)
return(
<div>
<p>theme1 color :{theme.color}</p>
<p>theme1 font :{theme.font}</p>
</div>
)
}
开始改变数据,抽离出按钮成为单独组件,当点击按钮时更改对象成为新的数据
先在根组件中把改变对象的方法定义好并传递给Setting组件
let changeTheme = ()=>{
setTheme({color:"green",font:"猫猫体"})
}
<Setting changeTheme ={changeTheme} />
在子组件中接收并使用这个方法。
function Setting (props){
const {changeTheme} = props
return(
<div>
<button onClick={changeTheme}>change theme</button>
</div>
)
}
- 二、结合useReducer使用----重点
const [state,dispatch] =useReducer(reducer,initState,init惰性初始化)
useReducer有三个参数,我们先来定义第2个参数
let initState = {color:"red",font:"bold"}
定义第一个参数,它是一个函数,规定他来改变state的状态
如果是red则,如果是green则。
let theme ={red:{color:"red",font:"bold"},green:{color:"green",font:"猫猫体"}}
function reducer(state,action){
switch (action) {
case "red":
return {...theme.red}
case "green":
return {...theme.green}
default:
return state
}
}
现在将初始状态先展示在根组件中:
const [theme,dispatch] = useReducer(ThemeReducer,initState)
此时的theme为initState初始数据,直接展示
<p>theme color : {theme.color}</p>
<p>theme font : {theme.font}</p>
再设置一个上下文,将theme与dispatch传入子组件中
const StateContext = createContext({})
provider包裹,在value中将theme与dispatch传入子组件中
<StateContext.Provider value={{theme,dispatch}}>
<Child1 />
<Setting />
</StateContext.Provider>
先来到Setting子组件使用useContext接收
const {theme,dispatch} = useContext(StateContext)
使用dispatch来改变为green
<button onClick={()=>{dispatch("green")}}>change theme</button>
再来到子组件中接收provider包裹传来的value值。
const {theme,dispatch} = useContext(StateContext)
//使用theme中的数据来展示
return(
<div>
<p>theme1 color :{theme.color}</p>
<p>theme1 font :{theme.font}</p>
</div>
)
两个钩子函数结合使用总结流程:
定义init初始数据,定义reducer函数方便来改变数据
来到根组件中使用useReducer接收reducer函数与初始数据参数
将useReducer的返回值[theme,dispatch]通过Provider中的value传递给子组件
子组件使用useContext接收value数据并加以使用