我正在学习 React 和 Redux,但我无法弄清楚为什么我的 React 组件在 Redux 存储状态更改后没有重新渲染。
这是我的代码:
const initialState = { value: 'Loading...' }
function onSetName(state = initialState, action) {
if (action.type === 'doc/docnamechanged') {
return {
...state,
value: action.payload
}
}
return state
}
export const setName = text => {
return {
type: 'doc/docnamechanged',
payload: text
}
}
export const store = configureStore({ reducer: onSetName })
store.subscribe(() => Layout(), App());
export default function App() {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/1" element={<PublicPage />} />
</Route>
</Routes>
)
}
这就是我的调度
if (store.getState().value != "AD") {
store.dispatch(setName("AD"));
}
function Layout() {
console.log(store.getState().value);
const name = store.getState().value;
return (
<div className="App">
<div className="header">
<img className="logo" src="images/logotype.png" alt="logo" />
<div className="UpperTitle">
{name}
</div>
</div>
</div>
)
}
所以我可以在控制台中看到 store.getState().value
确实改变了,但在渲染时<div className="UpperTitle">
{name}
不会改变。正如你所看到的,我也尝试订阅我的 App() 函数,但这根本没有帮助。感谢任何帮助。
如果我在index.js中订阅render(),我设法让它以某种方式工作,但这似乎是错误的并导致警告消息
react-dom.development.js:86 Warning: Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.
最佳答案
在组件中调用 store.getState
不会使其订阅任何更改,它只是获取一次状态,仅此而已。需要发生其他事情才能触发 Layout
组件重新渲染,以便再次调用 store.getState
。
但这不是我们在 React 组件中订阅存储的方式。您可以使用 connect
高阶组件,或更现代的useSelector
钩子(Hook)。
import { useSelector } from 'react-redux';
import { Outlet } from 'react-router-dom';
function Layout() {
const name = useSelector(state => state.value); // <-- subscribe to changes
useEffect(() => {
console.log({ name });
}, [name]);
return (
<div className="App">
<div className="header">
<img className="logo" src="images/logotype.png" alt="logo" />
<div className="UpperTitle">
{name}
</div>
</div>
<Outlet /> // <-- for the nested routes 😉
</div>
);
}
您需要确保将 Redux 存储提供给 React 应用程序。
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
const initialState = {
value: 'Loading...'
};
function onSetName(state = initialState, action) {
if (action.type === 'doc/docnamechanged') {
return {
...state,
value: action.payload
};
}
return state;
}
export const setName = text => ({
type: 'doc/docnamechanged',
payload: text,
});
export const store = configureStore({
reducer: onSetName,
});
export default function App() {
return (
<Provider store={store}>
<Routes>
<Route element={<Layout />}>
<Route path="/1" element={<PublicPage />} />
</Route>
</Routes>
</Provider>
);
}
既然您实际上已经在使用 Redux-Toolkit,那么您确实应该使用当前的 Redux 模式。
import { Provider } from 'react-redux';
import { configureStore, createslice } from '@reduxjs/toolkit';
const initialState = {
value: 'Loading...'
};
const nameSlice = createSlice({
name: "name",
initialState,
reducers: {
setName: (state, action) => {
state.value = action.payload;
},
},
});
export const {
...nameSlice.actions,
};
export const store = configureStore({
reducer: nameSlice.reducer,
});
import { setName } from '../path/to/name.slice';
...
dispatch(setName("AD"));
关于javascript - 为什么我的 React 组件不会在 Redux 存储状态发生变化时重新渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75563415/