在反应上下文中传递多个状态
Passing multiple states in react context
我有一个上下文应该在树的多个状态中传递。
设置 Provider 值的正确方法是什么?
- 在适当的位置创建 object 不起作用,因为它在每个 re-render 处都是 re-built,导致 child 也变为 re-render如果上下文的实际内容没有改变(因为创建了一个新的 object,具有不同的内存地址,导致 child 认为 object 已更改)。
我应该如何传递上下文?
//Example:
interface Context {
state1: number,
state2: number,
}
const MyContext = React.createContext<Context|null>(null)
const MyFC: React.FC = (props)=>{
const [state1,setState1] = useState<number>(0) //To pass down
const [state2,setState2] = useState<number>(0) //To pass down
const [state3,setState3] = useState<number>(0) //Not to pass down
return(
<MyContext.Provider value={????}>
{/* components */}
<MyContext>
)
}
您可以将键控数组传递给值:
value={{'state1':[state1,setstate1],'state2':[state2,setstate2]}}
然后您可以检索每个数据:
const context = React.useContext(MyContext);
const [state1,setstate1] = context['state1'];
const [state2,setstate2] = context['state2'];
或直接:
const [state1,setstate1] = React.useContext(MyContext)['state1'];
const [state2,setstate2] = React.useContext(MyContext)['state2'];
您可以添加多少个州。
在上下文中传递复杂状态的选项有多个。
选项 1:拆分不一起更改的上下文
如果构成上下文的元素不是紧密相关,请考虑将上下文拆分为不同的上下文。这样你就可以通过单个状态而不必处理“统一”状态的问题。
方案二:使用useReducer合并相关状态
When using useState hook is advised to create a separate state for
each element since, unlike the state in class components, updating
single elements of a state can lead to unnecessary complexity.
使用状态是功能组件中最常用的保存状态的工具。
然而,当需要更复杂的状态(和状态管理)时,useReducer 可用于将状态包装在单个对象中。然后你可以将 reducer 的状态作为 context
的值传递
function reducer(state,action) {
switch(action.type){
//Cases:
//.... (works like redux reducer)
default:
return state
}
}
const MyContext = React.createContext<Context|null>(null)
const MyFC: React.FC = (props)=>{
const [compressedState,dispatch] = useReducer(reducer,{state1:0,state2:0})
const [state3,setState3] = useState<number>(0) //Not to pass down
return(
<MyContext.Provider value={compressedState}>
{/* components */}
<MyContext>
)
}
选项 3:使用备忘录
当前面的选项都不可行时,useMemo 是可行的方法。
简单地组合所有需要传递的元素来创建一个值,该值仅在至少一个依赖项发生变化时更新。
const MyContext = React.createContext<Context|null>(null)
const MyFC: React.FC = (props)=>{
const [state1,setState1] = useState<number>(0) //To pass down
const [state2,setState2] = useState<number>(0) //To pass down
const [state3,setState3] = useState<number>(0) //Not to pass down
const contextValue= useMemo(()=>{
return{
state1: state1,
state2: state2
}
},[state1,state2]);
return(
<MyContext.Provider value={contextValue}>
{/* components */}
<MyContext>
)
}
关于 useMemo 的最后说明
当我们需要传递 useState(state 和 set state)或 useReducer(state 和 dispatch)的两个元素时,使用备忘录也变得有用。
在上下文中,我们应该始终避免将内联对象放入value
prop 中。正如 post 开头所说,这个对象在每次渲染(新内存地址)时都会重新创建,导致检查它的钩子重新渲染(因为观察到的内存值发生变化)以及向下小部件树。
在这种情况下,使用备忘录会变得很方便,因为它可以避免传递内联对象:
//Example for useReducer. Works also with useState.
const contextValue = useMemo(() => {
return { state, dispatch };
}, [state, dispatch]);
来源:
我有一个上下文应该在树的多个状态中传递。 设置 Provider 值的正确方法是什么?
- 在适当的位置创建 object 不起作用,因为它在每个 re-render 处都是 re-built,导致 child 也变为 re-render如果上下文的实际内容没有改变(因为创建了一个新的 object,具有不同的内存地址,导致 child 认为 object 已更改)。
我应该如何传递上下文?
//Example:
interface Context {
state1: number,
state2: number,
}
const MyContext = React.createContext<Context|null>(null)
const MyFC: React.FC = (props)=>{
const [state1,setState1] = useState<number>(0) //To pass down
const [state2,setState2] = useState<number>(0) //To pass down
const [state3,setState3] = useState<number>(0) //Not to pass down
return(
<MyContext.Provider value={????}>
{/* components */}
<MyContext>
)
}
您可以将键控数组传递给值:
value={{'state1':[state1,setstate1],'state2':[state2,setstate2]}}
然后您可以检索每个数据:
const context = React.useContext(MyContext);
const [state1,setstate1] = context['state1'];
const [state2,setstate2] = context['state2'];
或直接:
const [state1,setstate1] = React.useContext(MyContext)['state1'];
const [state2,setstate2] = React.useContext(MyContext)['state2'];
您可以添加多少个州。
在上下文中传递复杂状态的选项有多个。
选项 1:拆分不一起更改的上下文
如果构成上下文的元素不是紧密相关,请考虑将上下文拆分为不同的上下文。这样你就可以通过单个状态而不必处理“统一”状态的问题。
方案二:使用useReducer合并相关状态
When using useState hook is advised to create a separate state for each element since, unlike the state in class components, updating single elements of a state can lead to unnecessary complexity.
使用状态是功能组件中最常用的保存状态的工具。
然而,当需要更复杂的状态(和状态管理)时,useReducer 可用于将状态包装在单个对象中。然后你可以将 reducer 的状态作为 context
的值传递function reducer(state,action) {
switch(action.type){
//Cases:
//.... (works like redux reducer)
default:
return state
}
}
const MyContext = React.createContext<Context|null>(null)
const MyFC: React.FC = (props)=>{
const [compressedState,dispatch] = useReducer(reducer,{state1:0,state2:0})
const [state3,setState3] = useState<number>(0) //Not to pass down
return(
<MyContext.Provider value={compressedState}>
{/* components */}
<MyContext>
)
}
选项 3:使用备忘录
当前面的选项都不可行时,useMemo 是可行的方法。 简单地组合所有需要传递的元素来创建一个值,该值仅在至少一个依赖项发生变化时更新。
const MyContext = React.createContext<Context|null>(null)
const MyFC: React.FC = (props)=>{
const [state1,setState1] = useState<number>(0) //To pass down
const [state2,setState2] = useState<number>(0) //To pass down
const [state3,setState3] = useState<number>(0) //Not to pass down
const contextValue= useMemo(()=>{
return{
state1: state1,
state2: state2
}
},[state1,state2]);
return(
<MyContext.Provider value={contextValue}>
{/* components */}
<MyContext>
)
}
关于 useMemo 的最后说明 当我们需要传递 useState(state 和 set state)或 useReducer(state 和 dispatch)的两个元素时,使用备忘录也变得有用。
在上下文中,我们应该始终避免将内联对象放入value
prop 中。正如 post 开头所说,这个对象在每次渲染(新内存地址)时都会重新创建,导致检查它的钩子重新渲染(因为观察到的内存值发生变化)以及向下小部件树。
在这种情况下,使用备忘录会变得很方便,因为它可以避免传递内联对象:
//Example for useReducer. Works also with useState.
const contextValue = useMemo(() => {
return { state, dispatch };
}, [state, dispatch]);
来源: