useContext和useReducer 可以用来减少层级使用, useContext,可以明白为供货商提供一个公共的共享值,然后下面的斲丧者去担当共享值,只有一个供货商,而有多个斲丧者,可以到达共享的状态改变的目的。
useReducer 可以和 useContext 共同使用,useReducer 可以明白为全部的公共组件共享状态。有多个组件,但是都要共享同一个状态和改变状态后的值,这时间就须要公共的useReducer来改变了。
下面通过代码具体解说怎样使用useContext 和useReducer
一. useContext根本使用可以分为固定的三步
1.根组件导入并调用createContext方法,得到Context对象
import React, { useContext } from 'react'const GlobalContext = React.createContext()2.在根组件中使用 Provider 组件包裹须要吸收数据的后代组件,并通过 value 属性提供要共享的数据
<GlobalContext.Provider value={ { title: "12313", info: info, changeInfo: (value) => { setInfo(value) } } }></GlobalContext.Provider>3.须要获取公共数据的后代组件:
a) 导入useContext,并按需导入根组件中导出的Context对象;
b) 调用useContext(第一步中导出的Context) 得到value的值
a) const value = useContext(GlobalContext)return ( <div onClick={() => { value.changeInfo(context); }}> {value.title} </div> )b)return ( <GlobalContext.Consumer> { (value) => <div className='business-product-details' > {value.info} </div> } </GlobalContext.Consumer> )4.完备例子
import React, { useState, useEffect, useContext } from 'react'import axios from 'axios'import './css/index.css'const GlobalContext = React.createContext()export default function app() { const [list, setlist] = useState([]) const [info, setInfo] = useState("") useEffect(() => { axios.get("./test.json").then(res => { setlist(res.data[2].list) }) }, []) return ( <GlobalContext.Provider value={ { title: "12313", info: info, changeInfo: (value) => { setInfo(value) } }}> <div className="w-warp"> <div className="business-why"> <div className='business-ul'> { list && list.map((item, index) => <ReasonLi key={index} {...item} ></ReasonLi> ) } </div> <ReasonDetails /> </div> </div> </GlobalContext.Provider> )}function ReasonLi(props) { let { name, url, context } = props const value = useContext(GlobalContext) return ( <div className="business-product" onClick={() => { value.changeInfo(context); }}> <div className='business-img'><img src={url} alt={name} /></div> <h5>{name}</h5> </div> )}function ReasonDetails() { return ( <GlobalContext.Consumer> { (value) => <div className='business-product-details' > {value.info} </div> } </GlobalContext.Consumer> )}二. useReducer根本使用可以分为固定的三步
1.页面引入 useReducer 而且创建相干对象
import React, { useReducer} from 'react'父组件创建 const [state, dispatch] = useReducer(reducer, intialState)2.页面根组件界说reducer的函数和初始状态值intialState
reducer里面包罗两个参数(prevState,action) 之前状态值和 操纵改变的范例
界说初始状态值 intialState 可以是对象包罗多个值
const reducer=(prevState,action) => { console.log(prevState,acton) // count:0 ,action.type:minus}const intialState = { count:0}const intialState = { count:0}3.父组件界说相干的dispatch状态改变操纵范例
<button onClick={() => { dispatch({ type: "minus" }) }}>-</button>4.完备例子
import React, { useReducer } from 'react'const reducer=(prevState,action) => { const newState = {...prevState} switch (action.type) { case 'minus': newState.count--; return newState ; case 'add': newState.count++; return newState default: return newState }}const intialState = { count:0}export default function app() { const [state,dispatch] = useReducer(reducer,intialState) return ( <div> <button onClick={() => { dispatch({ type: "minus" }) }}>-</button> {state.count} <button onClick={() => { dispatch({ type: "add" }) }}>+</button> </div> )}这个一个简单的数字加加和减减,根据的是action的范例判断状态的改变。下面看一个例子是useReducer结合useContext使用的例子。如果共享状态值和共享改变后的状态值。
如下效果
此中两个按钮是组件1,child2 和child3 为组件2 和组件3 ,通过组件1的操纵改变组件2和组件3的值共享之前的状态和改变之后的状态,具体demo如下
import React, { useReducer, useContext } from 'react'const intialState = { a: "1111", b: "22222"}const reducer = (prevState, action) => { let newState = { ...prevState } switch (action.type) { case "child2": newState.a = "aaaa"; return newState; case "child3": newState.b = "bbbb"; return newState; default: return newState; }}const GlobalContext = React.createContext()export default function app() { const [state, dispatch] = useReducer(reducer, intialState) return ( <GlobalContext.Provider value={ { state: state, dispatch: dispatch } }> <div> <Child1></Child1> <Child2></Child2> <Child3></Child3> </div> </GlobalContext.Provider>)}function Child1() { const value = useContext(GlobalContext) return (<div> <button onClick={() => { value.dispatch({ type: "child2" }) }}>改变child2</button> <button onClick={() => { value.dispatch({ type: "child3" }) }}>改变child3</button> </div> )}function Child2() { const value = useContext(GlobalContext) return ( <div style={{ background: "yellow" }}> Child2 {value.state.a} </div> )}function Child3() { const value = useContext(GlobalContext) return ( <div style={{ background: "blue" }}> Child3 {value.state.b} </div> )} |