我有一个跟踪各种服务器信息的应用程序。我有一个web服务器,我可以通过服务器名来查询信息。我为这个信息创建了一个上下文,该上下文以服务器名称作为支柱,并定期更新其数据。见下文;
ServerContext.js
export const ServerDataContext = createContext();
export const ServerDataContextProvider = ({
children,
server= "",
}) => {
const [serverConfig, setServerConfig] = useState({});
const updateServerData = () => {;
serverConfigRequest(server).then((res) => {
setServerConfig((old) => {
return res;
});
});
};
useEffect(() => {
console.log("init");
updateServerData();
const updateInterval = setInterval(
updateServerData,
serverConfigUpdateFrequency * 1000
);
return () => {
clearInterval(updateInterval);
};
}, []);
return (
<ServerDataContext.Provider
value={{
serverConfig,
}}
>
{children}
</ServerDataContext.Provider>
);
};在我的App.js中,我使用react路由器来为每个服务器拥有一个StatusPage。看起来是这样的:
App.js
function App() {
return (
<Router>
<div className="app">
<Header />
<Routes>
<Route exact path="/" element={<div>Overview</div>} />
<Route
exact
path="/server_1"
element={
<ServerDataContextProvider server="server_1">
<StatusPage server="server_1" />
</ServerDataContextProvider>
}
/>
<Route
exact
path="/server_2"
element={
<ServerDataContextProvider server="server_2">
<StatusPage server="server_2" />
</ServerDataContextProvider>
}
/>
</Routes>
<Footer />
</div>
</Router>
);
}我有按钮要转到标题中的每一页。当我加载第一个服务器状态页面时,页面更新非常好。我看到服务器上的请求以正确的间隔进入server_1,然后导航到server_2,在浏览器搜索栏中看到路由更新,但是页面上的内容没有。我在我的web服务器上收到的请求仍然是针对server_1的,就像我没有切换页面一样。如果我仍然在server_2的端点刷新页面,页面上的内容将为server_2正确更新,但这次server_1也会出现同样的问题。
我是否不恰当地使用上下文?我认为问题在于我是如何构造这个应用程序的,但我不确定。如有任何建议,敬请见谅。
编辑:https://codesandbox.io/s/admiring-haibt-vxm62?file=/src/ServerContext.js
发布于 2021-11-18 19:08:51
我在这里怀疑的是,当路由路径切换时,反应树实际上是相同的,服务器2的上下文提供程序也没有被挂载。我肯定根本没有看到它挂载,即使安装了useEffect__,服务器1上下文值仍然被提供。
在App中向每个提供程序添加一个React当然会起到作用,并通知React,它们实际上是两个不同的组件,它必然需要用给定的道具重新装入提供程序,并恢复上下文值。
<Routes>
<Route path="/" element={<div>Overview</div>} />
<Route
path="/server_1"
element={
<ServerDataContextProvider key="server_1" server="server_1">
<StatusPage server="server_1" />
</ServerDataContextProvider>
}
/>
<Route
path="/server_2"
element={
<ServerDataContextProvider key="server_2" server="server_2">
<StatusPage server="server_2" />
</ServerDataContextProvider>
}
/>
</Routes>


或者,将server支柱添加为ServerDataContextProvider的useEffect挂钩中的依赖项也将清除任何现有的间隔计时器,并使用更新的server支柱的值重新启动它们。
useEffect(() => {
// moved into effect callback to remove as dependency
const updateServerData = () => {
setServerConfig((old) => {
return { server: server == "server_1" ? "G" : "R" };
});
};
console.log("init");
updateServerData();
const updateInterval = setInterval(updateServerData, 5 * 1000);
return () => {
clearInterval(updateInterval);
};
}, [server]);https://stackoverflow.com/questions/70024530
复制相似问题