我已经崩溃了,试图解决这个问题已经三天了。我似乎无法获得我的react-route的子组件来接收传递给它的道具。而是使用未定义的方式渲染它们。
流程如下:
submitFile -> (Callback) -> App (set state using useState hooks) -> Dashboard
我已检查并且回调正常运行,因此数据返回到App和console.log确认已设置状态。但是我真的不明白为什么使用未定义的props创建Dashboard组件。任何帮助将不胜感激。我已经尝试了许多不同的东西,并阅读了许多线程和文档,坦率地说,我即将爆炸!
请参见下面的代码: App.js
export default function App() {
const [authState, setState] = useState(false);
const [jobId, setJobId] = useState(false);
const [token, setToken] = useState(false);
const [apiKey, setApiKey] = useState(false);
const authCallbackState = authStateData => {
setState(authStateData);
};
const jobCallback = (jobId_, token_, apiKey_) => {
setJobId(jobId_);
setToken(token_);
setApiKey(apiKey_);
};
return (
<ThemeProvider theme={theme}>
<Router>
<Switch>
<Route
path="/dashboard"
render={() =>
authState && apiKey ? (
<Dashboard jobId={jobId} token={token} apiKey={apiKey} />
) : (
<h1>loading</h1>
)
}
></Route>
<PrivateRoute path="/submitFile" authState={authState}>
<CssBaseline />
<SubmitFile dbCallback={jobCallback} />
</PrivateRoute>
<Route path="/">
<AuthComponent appCallback={authCallbackState} />
</Route>
</Switch>
</Router>
</ThemeProvider>
);
}
如您所见,我已经做到了,因此仪表板仅在链接中进行切换后才呈现,至少这些值应该为false而不是未定义?
使用道具的仪表板功能
export default function Dashboard(props) {
/**
* Polls the API at 30 second intervals to check job status
*
*/
const getFile = async e => {
const url = baseUrl + '/get_results';
const headers = { headers: { 'x-api-key': props.apiKey, Authorization: props.token } };
console.log(headers['Authorization']);
const interval = setInterval(() => {
axios.get(url, props.jobId, headers).then(response => {
if (response.status === 200) {
setProgress(100);
showWaitMessage(false);
setFile(response.data);
clearInterval(interval);
}
if (response.status === 202) {
if (progress < 100) {
setProgress(progress + 10);
} else if (!ackWaitMessage) {
showWaitMessage(true);
}
}
if (response.status === 403) {
// show some error message
clearInterval(interval);
}enter code here
if (response.status === 400 || 404) {
showErrorMessage(true);
clearInterval(interval);
}
});
}, 30000);
};
答案 0 :(得分:0)
setInterval
获得关闭并每次使用相同的道具进行投票。
您可以使用useEffect
钩子来更新轮询功能:
useEffect(() => {
const watcher = setInterval(....);
return () => clearInterval(watcher);
}, [props.jobId, props.token, props.apiKey]);
或者您可以将当前的道具存储在useRef
中:
const propsRef = useRef(props);
propsRef.current = props;
并在propsRef.current.jobId
内以getFile
的身份访问它们
答案 1 :(得分:0)
很抱歉浪费大家的时间。当我在子组件中具有以下useEffect时,我以为以前很聪明:
useEffect(() => {
console.log(props.jobId);
getFile();
}, []);
由于空的依赖项数组,显然将其锁定在子状态。 DOH!
我已将其更新为
useEffect(() => {
console.log(props.jobId);
getFile();
}, [props.jobId, props.apiKey, props.token]);```
and it works fine.