Reactjs 使用useEffect对状态更改作出反应

Reactjs 使用useEffect对状态更改作出反应,reactjs,react-redux,react-hooks,Reactjs,React Redux,React Hooks,我对hooks有点陌生,我正在使用一种我不知道是否可取的模式。 我所做的是将redux与useEffect挂钩混合在一起,对于每一个有意义的状态更改,我的一个挂钩都会被触发并更新一些状态 例如,如果我的减速器中有一个错误字段。我写了这样的东西 useffect(()=>{ if(state.error&!state.error.open){ showSnackbar(state.error.text) } },[state.error]) 当用户关闭snackbar时,我清除错误 或 如果我想

我对hooks有点陌生,我正在使用一种我不知道是否可取的模式。 我所做的是将redux与useEffect挂钩混合在一起,对于每一个有意义的状态更改,我的一个挂钩都会被触发并更新一些状态

例如,如果我的减速器中有一个错误字段。我写了这样的东西

useffect(()=>{
if(state.error&!state.error.open){
showSnackbar(state.error.text)
}
},[state.error])
当用户关闭snackbar时,我清除错误

如果我想通过获取数据和更改页面来对按钮单击作出反应,请使用:

(我显式设置user clicked的原因是,当用户在下一页中单击back按钮时,我不会再次重定向到该页,因为数据仍然存在于存储中。)

useffect(()=>{
如果(按钮单击&&state.someData.id>0){
历史。推送('/route');
}
},[state.someData,按钮勾选];
handleClick=()=>{
分派(actions.fetchSomeData());
setUserClicked();
}
在我的组件中,有时我有7-8个useEffects处理不同的事情,其中大多数都有条件行为

我经常看到这样的代码:

const result=等待调度(someAction);
if(result.payload.error)
{
//...
}
其他的
{
历史。推挤(…);
}
与使用多个生命周期挂钩相比,此模式是否有一些优势

也许我使用第一种方式是因为它更具陈述性?但是有很多有用的效果好吗?在上面的代码中,我在两个钩子中处理了错误和成功


谢谢。

如果你写了太多的
useffect
,这暗示你的组件太大了。您应该开始考虑创建更小的功能性/无状态组件(无需呈现任何标记)。对于结构良好的代码,每个组件有几页代码是最大的大小。 更新:以下是无效代码:

if(buttonClicked && state.someData.id > 0) {
    return <Redirect to="/route" />
}

handleClick = () => {
    dispatch(actions.fetchSomeData());
    setUserClicked();
}
if(按钮点击&state.someData.id>0){
返回
}
handleClick=()=>{
分派(actions.fetchSomeData());
setUserClicked();
}

您可以根据组件的需要使用尽可能多的效果。我还认为在按钮onClick事件上使用
preventDefault
,可能会对您有所帮助。第二种模式是我看到在异步redux操作中使用得更多的模式,比如用于获取数据的API调用,通常使用Thunks(redux-thunk)之类的中间件,但这通常是为了允许在请求获取/处理逻辑与组件代码解耦的同时将错误直接返回到UI。我使用preventDefault,但为了简洁起见,我删除了这些部分。我的useEffects的主要用例是对状态更改(无论是异步还是同步)进行响应。大多数时候,它们都在我的容器中,而不是组件中。我的意思是,我没有等待异步操作来获得响应并使用该响应来触发另一个操作,而是将事件侦听器(useEffect)挂接到该特定数据,当它被填充时,我触发另一个操作。可以吗?当然可以。这就是效果的作用;对依赖项数组中的值的任何更改都会触发它们运行其副作用回调。请立即检查我的代码。我在一个文件中最多有10个useEffects,在一个组件中我的代码的最大大小约为300-350行。根据你的回答,我想应该没问题吧?我担心在这类任务中使用useEffect是不合适的。如果你去掉useEffect并在渲染前进行定期的If检查,它应该可以正常工作:`If(buttonClicked&&state.someData.id>0){return}`你可能在不需要效果的地方使用效果。