反应儿童道具不被遗忘

时间:2020-07-29 13:51:15

标签: reactjs

我已经崩溃了,试图解决这个问题已经三天了。我似乎无法获得我的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);
    };

2 个答案:

答案 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.