JDa*_*oer 11 reactjs react-hooks
当您具有涉及多个子值的复杂状态逻辑时,或者当下一个状态取决于上一个状态时,useReducer通常比useState更可取。useReducer还可以让您优化触发深层更新的组件的性能,因为您可以传递调度而不是回调。
(引自https://reactjs.org/docs/hooks-reference.html#usereducer)
我对粗体部分感兴趣,该部分指出useReducer应useState在上下文中使用而不是使用。
我尝试了两种变体,但它们似乎没有什么不同。
我比较这两种方法的方式如下:
const [state, updateState] = useState();
const [reducerState, dispatch] = useReducer(myReducerFunction);
Run Code Online (Sandbox Code Playgroud)
我将它们每个都传递给一个上下文对象,该上下文对象被一个更深的孩子使用(我只是运行了单独的测试,将值替换为要测试的函数)。
<ContextObject.Provider value={updateState // dispatch}>
孩子包含这些功能
const updateFunction = useContext(ContextObject);
useEffect(
() => {
console.log('effect triggered');
console.log(updateFunction);
},
[updateFunction]
);
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,当父级重新渲染时(由于另一个局部状态更改),效果永远不会运行,这表明在渲染之间更新功能未更改。我看错了引号中的粗体字吗?还是我忽略了什么?
useReducer还可以让您优化触发深层更新的组件的性能,因为您可以传递调度而不是回调。
上面的语句并不是要表明useState在每次更新或渲染时都正在重新创建由返回的setter 。这意味着当您有复杂的逻辑来更新状态时,您根本不会直接使用setter来更新状态,而是您将编写一个复杂的函数,该函数会依次调用具有更新状态的setter,例如
const handleStateChange = () => {
// lots of logic to derive updated state
updateState(newState);
}
ContextObject.Provider value={{state, handleStateChange}}>
Run Code Online (Sandbox Code Playgroud)
现在,在上述情况下,每次重新渲染父对象时,都会创建一个新的handleStateChange实例,从而使Context Consumer也重新渲染。
上述情况的解决方案是使用useCallback并记住状态更新程序方法并使用它。但是,为此,您需要注意与使用方法中的值相关的关闭问题。
因此,建议使用useReducerwhich返回dispatch在重新渲染之间不变的方法,并且可以在化简器中使用操作逻辑。
useReducer 和 useState 的实际观察 -
使用状态:
在我的 React Native 项目中,我有 1 个屏幕,其中包含使用useState.
我useEffect (componentDidMount)根据某些条件调用 api 并获取响应,我设置这 25 个状态,为每个函数调用 25 个状态设置器函数。
我已经设置了重新渲染计数器并检查了我的屏幕是否重新渲染了14次数。
重新渲染计数同样:
let count = 0;
export default function Home(props) {
count++;
console.log({count});
//...
// Rest of the code
}
Run Code Online (Sandbox Code Playgroud)
使用Reducer:
然后我将这 25 个状态移到 useReducer 状态中,并且仅使用单个操作来更新 API 响应上的这些状态。
我观察到只有 2 次重新渲染。
//API calling method:
fetchData()
{
const response = await AuthAxios.getHomeData();
dispatch({type: 'SET_HOME_DATA', data: response.data});
}
//useReducer Code:
const initialStaes = {
state1: null,
state2: null,
//.....More States
state27: null,
state28: null
}
const HomeReducer = (state, action) => {
switch (action.type) {
case 'SET_HOME_DATA': {
return {
...state,
state1: (Data based on conditions),
state2: !(some Conditions ),
//....More states
state27: false
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下 useReducer 的优点:
| 归档时间: |
|
| 查看次数: |
870 次 |
| 最近记录: |