我有几十个使用Redux Thunk中间件触发异步API请求的实例,例如:
const someHandler = async () => {
const result = await dispatch(someAsyncApiCallActionCreator());
// ... do something with the result
}我需要更改行为,使其首先显示一个组件,并在实际调用之前等待用户交互(单击按钮),同时保持上面所示的初始分派不变。
显示部分很简单,我可以在我的操作创建器中首先切换状态中的属性:
const someAsyncApiCallActionCreator = params => dispatch => {
// Trigger property state change first in this action:
dispatch(showMyComponent());
// Proceed
return fetch(...);
}然而,我无法理解如何延迟接下来的fetch调用,直到组件中的按钮被按下。
如果我在状态中存储一个promise,然后在组件中选择并解析它,那么它可以工作,但是由于不应该在状态中存储不可序列化的数据,所以这似乎不是一个好方法。
有没有其他可能的方法,同时保持来自上面的初始调用完好无损,而不需要更改几十次调用?
发布于 2020-10-10 04:54:13
一般来说,将UI状态保持在本地组件状态而不是redux状态被认为是更好的做法。因此,您可能希望避免使用此dispatch(showMyComponent())。
从分派返回状态也是一种糟糕的做法。分派应该处理获取值并将其设置为状态。检索应该使用选择器来完成。选择器在第一次调用时将返回null/undefined/等,因为数据尚未加载,但是一旦您调用的操作加载了数据,connect()或useSelector将订阅更改并检索更新后的值。
在执行fetch时,只需在单击按钮之前不要调用someHandler。
下面是一个示例设置,我们根据是否加载数据在显示按钮和显示数据之间进行切换。您还可以添加第三个选项,用于在按钮被单击但数据尚未加载时显示,以及第四个选项,用于在获取数据时出错,等等。这只是一个起点。
const MyComponent = (props) => {
// data will be undefined until it is exists in the state
const data = useSelector(someSelector);
const isLoaded = data !== undefined;
const dispatch = useDispatch();
const someHandler = () => {
// don't await any return. just dispatch
dispatch(someAsyncApiCallActionCreator(props.param))
}
return (
<div>
{isLoaded ?
<LoadedComponent data={data}/>
:
<button onClick={() => someHandler()}>Load Data</button>
}
</div>
)
}https://stackoverflow.com/questions/64261274
复制相似问题