【发布时间】:2021-10-23 09:46:31
【问题描述】:
所以我简化了我的代码,但基本上我有一个直截了当的 redux 商店:
/* store.js */
import { createStore } from 'redux';
const reducer = (state = {}, action) => {
if (action.type === 'action') state.data = data;
return state;
}
const store = createStore(reducer);
store.subscribe(() => {
console.log(store.getState()); // returns the right state, updates properly
});
export default store;
从服务器拉取数据并将其分派到存储的加载器:
/* Loader.js */
class Loader {
dispatch (allDocuments) {
store.dispatch({
type: 'action',
data: data
});
}
async fetchData () {
try {
const allDocuments = await ajaxCall('GET', '/fetchData');
this.dispatch(allDocuments);
return allDocuments;
} catch (e) {
console.error(e);
}
}
}
export default Loader;
然后这是我的 App.js 文件,我每 5 秒触发一次 Loader fetch 方法并将存储状态映射到 React 组件:
/* App.js */
import Loader from './Loader';
const loader = new Loader();
setInterval(async () => {
await loader.fetchData();
}, 5000);
const App = ({
data
}) => {
console.log(data); //doesn't update
return (
<div>
<p>{data}</p>
</div>
)
};
const mapStateToProps = state => ({data: state.data,})
export default connect(mapStateToProps)(App);
所以这里的问题是组件没有更新。 Loader 正确调度,redux store 确实得到了更新,但 App 中的 data prop 仍然是一个空对象,并且不会重新触发 render 方法。
为什么mapStateToProps在store状态改变时不更新组件?
【问题讨论】:
-
App是否包含在 redux 存储提供程序中,提供您在外部使用的相同存储? -
我越看这段代码,就越讨厌它。您的
setInterval在组件之外,它永远不会停止。您的Loader直接访问store而不是使用 react-redux 绑定 (connect/useDispatch)。我认为这是一个错字,但data中的data变量到底是什么?! -
我完全同意 Linda 的观点……这段代码所做的几乎所有事情都应该被视为 React 组件生命周期结构中的反模式。 redux store 是不是特定于 React 的大型应用程序的一部分吗?在 React 中,您几乎不会直接使用
store对象来调度操作。 -
对于尝试做的事情,即每 5 秒重新获取数据并将其存储在 Redux 中,我建议使用 RTK Query 的内置“轮询”功能:redux-toolkit.js.org/rtk-query/usage/polling
-
等等,为什么 Loader 在 React 组件之外是一件坏事?让一个非反应类在没有任何 ui 的情况下从服务器更新数据然后让前端元素使用它是否没有意义?
标签: reactjs redux react-redux