我有一个使用 redux-state-sync 的示例 stackblitz 应用程序,它描述了当调用函数
initStateWithPrevTab
时,窗口无法从其他窗口获取初始状态的问题。
预期行为(也在我的旧 Angular 应用程序中得到确认):
/
的“主窗口”并调度状态更改/properties/
但是我链接的示例应用程序的工作原理如下:
/
的“主窗口”并调度状态更改/properties/
/properties/
窗口从“主窗口”接收整个状态并调度receiveIniteState
,但它没有任何效果。
因此,只有上一个选项卡(“主窗口”)的初始状态不会同步到新窗口(/properties/)。打开 /properties/ 窗口后的所有状态更改都会毫无问题地同步。代码如下所示:
store.ts
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
export const store = configureStore({
reducer: {
appProperties: appPropertiesReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(createStateSyncMiddleware()),
});
initStateWithPrevTab(store);
AppProperties.slice.ts
interface AppPropertiesState {
propertiesId: string;
}
const initialState: AppPropertiesState = {
propertiesId: '0',
};
const propertiesSlice = createSlice({
name: 'app-properties',
initialState,
reducers: {
setPropertiesId(state, action: PayloadAction<string>) {
state.propertiesId = action.payload;
},
},
});
export const { setPropertiesId } = propertiesSlice.actions;
export const selectPropertiesId = (state: RootState) =>
state.appProperties.propertiesId;
export const getInitialState = propertiesSlice.getInitialState;
export default propertiesSlice.reducer;
索引.ts
const root = createRoot(document.getElementById('app'));
root.render(
<StrictMode>
<App name="StackBlitz" />
</StrictMode>
);
应用程序.tsx
export const App: FC<{ name: string }> = ({ name }) => {
return (
<div>
<Provider store={store}>
<BrowserRouter>
<Routes>
<Route path="/" element={<MainView />} />
<Route path="properties" element={<Properties />} />
</Routes>
</BrowserRouter>
</Provider>
</div>
);
};
MainView.tsx
let i = 0;
export function MainView() {
function onSetPropertiesId(): void {
store.dispatch(setPropertiesId((++i).toString()));
}
const propertiesId = useSelector(selectPropertiesId);
return (
<div>
<p>Click the button increment propertiesId</p>
<button onClick={onSetPropertiesId}>Increment</button>
<p>Properties Id : {propertiesId}</p>
</div>
);
}
属性.tsx
export function Properties() {
const [content, setContent] = useState<ReactNode | undefined>(undefined);
const propertiesId = useSelector(selectPropertiesId);
useEffect(() => {
setContent(<span>PropertiesId : {propertiesId}</span>);
}, [propertiesId]);
return <div>{content}</div>;
}
如何在示例 stackblitz 应用程序中重现它:
之后同步就可以了。所以问题是,为什么即使调用了
initStateWithPrevTab
,第二个窗口也没有从前一个窗口初始化状态?正如之前提到的,库中的初始状态同步有效,并且我在旧的 Angular 应用程序中没有任何问题。
您似乎遇到了一个问题,即在 StackBlitz 应用程序中使用 Redux State Sync 在多个窗口之间未正确同步初始状态。让我们尝试排查并解决这个问题。
您可以采取以下几个步骤来调试问题:
检查 Redux State Sync 配置:确保您的 Redux State Sync 配置设置正确。确保在创建存储之后和分派任何操作之前调用 initStateWithPrevTab(store)。
验证窗口之间的通信:确认窗口之间的通信按预期工作。您可以通过添加控制台日志或使用浏览器开发人员工具来查看主窗口和属性窗口之间是否正确发送和接收消息来完成此操作。
检查初始状态:检查属性窗口的初始状态是否与主窗口的状态匹配。您可以在两个窗口中记录初始状态,看看是否有任何差异。
检查是否有任何错误或警告:在浏览器控制台中查找可能表明 Redux State Sync 设置或 Redux 减速器/操作存在问题的任何错误或警告。
查看 Redux State Sync 文档:浏览为 Redux State Sync 提供的文档和示例,以确保您在应用程序中正确使用它。
在不同的环境中进行测试:尝试在不同的浏览器或环境中运行您的应用程序,看看问题是否仍然存在。可能是浏览器特定的问题导致了该问题。
通过执行这些步骤,您应该能够确定问题的原因并找到解决方案,以确保 StackBlitz 应用程序中的多个窗口之间的初始状态正确同步。如果您仍然遇到问题,如果您认为这是库本身的问题,您可能需要考虑联系 Redux State Sync 社区或提交错误报告。