【问题标题】:Return component message for 5 seconds and then redirect返回组件消息 5 秒,然后重定向
【发布时间】:2021-01-20 08:31:35
【问题描述】:

我想要实现这样一种情况,如果我导航到我的 URL 时使用不正确的查询参数,则会显示一条消息,然后我会重定向到另一个页面。

想象一下,当您未登录时,尝试导航到只有登录用户才能看到的页面。我希望它呈现类似“您需要登录才能看到此内容”之类的内容,然后在 2 - 5 秒后页面重定向到/login 页面。

注意:包含的部分代码只是伪代码。

我知道我可以显示登录页面或使用简单的三进制重定向

return hasQueryParams ? <MyLoggedInPage /> : <Redirect to={`/login`} />

但是,我似乎无法获得 setTimeout 来延迟重定向...

const redirect = () => {
        let redirect = false;

        setTimeout(() => {
            redirect = true;
        }, 5000);

        return redirect
            ? <Redirect to={`/login`} />
            : <h1>Need to be logged in for that</h1>;
    }

return redirect();

为此,我收到一个错误:Functions are not valid as a React child. This may happen if you return a Component instead of &lt;Component /&gt; from render. Or maybe you meant to call this function rather than return it

我也尝试过使用useState

const [redirectNow, setRedirectNow] = useState(false);

useEffect(() => {
    // Some code unrelated to the timeout/redirect
}, []);

const redirect = () => {
        setTimeout(() => {
            setRedirectNow(false);
        }, 5000);

        return redirectNow
            ? <Redirect to={`/login`} />
            : <h1>Need to be logged in for that</h1>;
    }

return redirect();

但这也会得到一个不同的错误:Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3

通过进一步阅读,我了解到我们无法从事件处理程序内部访问 useState 内容。

更新

我还应该补充一点,此时我已经将useEffect 用于其他事情。

【问题讨论】:

    标签: javascript reactjs redirect use-state


    【解决方案1】:
    1. 使用状态来跟踪是否重定向。
    2. 间隔后更新状态。
    3. 更新状态时重定向。
    function RedirectComponent() {
      const [shouldRedirect, setShouldRedirect] = React.useState(false);
    
      React.useEffect(() => {
        const id = setTimeout(() => {
          setShouldRedirect(true);
        }, 5000);
    
        return () => clearTimeout(id);
      }, []);
    
      if (shouldRedirect) return <Redirect to="/login" />
    
      return <h1>This is the message</h1>
    }
    

    【讨论】:

    • 嗯...我仍然收到相同的错误显示,当我尝试在超时内设置状态时注意到...我忘了提到我已经在使用@987654322 @,所以只是想知道这是否会导致问题。
    • 问题可能不是来自这个组件。你能创建一个可重现的问题吗?
    • 不泄露商业机密 ;-)
    • 您应该隔离问题的实例并创建一个最小的可重现问题。问题可能出在其他地方。
    【解决方案2】:

    我更喜欢使用custom hook

    在这种情况下,useSetTimeout 可以工作。

    import React, { useState, useEffect, useRef } from 'react';
    
    function useSetTimeout(timeoutCallback, seconds) {
        const timeoutId = useRef();
    
        useEffect(() => {
            timeoutId.current = setTimeout(timeoutCallback, seconds);
            return () => clearTimeout(timeoutId.current);
        }, [])
    }
    
    function YourComponent(){
      const [redirectNow, setRedirectNow] = useState(false);
      useSetTimeout(()=>{
        setRedirectNow(true);
      }, 5000);
      return redirectNow ? <Redirect to={`/login`} /> : <h1>Need to be logged in for that</h1>;
    }
    

    【讨论】:

    • 嗯。它似乎也不喜欢这个。我认为问题在于 react 不希望您从 useEffect... 中调用 setState....同样的错误:-/
    • @physicsboy 您可以在您的位置多次使用useEffect
    • 我以为是这样,但由于某种原因我无法让它工作。
    猜你喜欢
    • 1970-01-01
    • 2012-12-12
    • 2013-11-19
    • 2016-04-06
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多