【问题标题】:State in React not updating as expectedReact 中的状态未按预期更新
【发布时间】:2020-08-14 04:10:13
【问题描述】:

在我的主要App.js 组件中,我正在尝试更新我的状态

const[isAuthenticated, setIsAuthenticated] = useState(false)

当我加载我的用户给定我在本地存储中的令牌时为真。

useEffect(() => {
  const loadUser = async () => {
    await fetch('http://localhost:5000/api/auth', {
      method: 'GET',
      headers: {
        'x-auth-token': localStorage.token,
      },
    });

    setIsAuthenticated(true);
  };
  
  loadUser();
}, []);

在我的回报中,我正在渲染一个私有组件......

<PrivateRoute exact path='/upload' component={Upload} isAuthenticated={isAuthenticated} />

我的PrivateRoute.js 文件看起来像这样...

const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
  <Route
    {...rest}
    render={(props) =>
      isAuthenticated ? <Component {...props} /> : <Redirect to='/login' />
    }
  />
);

几乎通过将isAuthenticated 作为道具传递给我的PrivateRoute 组件,我认为isAuthenticated 应该更新为true。我通过检查从我提出的请求中返回的数据来检查我是否正确加载了用户,并且确实我得到了用户并且setIsAuthenticated 被调用

但是,当我在加载用户后尝试检查isAuthenticated 中的PrivateRoute 时,我得到isAuthenticatedfalse

我不确定为什么会这样,非常感谢一些帮助和解释。

我的 App.js 文件如下所示...

const App = () => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    const loadUser = async () => {
      await fetch('http://localhost:5000/api/auth', {
        method: 'GET',
        headers: {
          'x-auth-token': localStorage.token,
        },
      });

      localStorage.setItem('token', localStorage.token);
      setIsAuthenticated(true);
    };

    loadUser();
  }, []);

  return (
    <Router>
      <div className='d-flex flex-row mb-5'>
        <Menu />
        <div className='d-flex flex-column mt-5 w-100'>
          <Switch>
            <Route exact path='/' component={Home} />
            <Route exact path='/login' component={SignIn} />
            <PrivateRoute
              exact
              path='/upload'
              component={Upload}
              isAuthenticated={isAuthenticated}
            />
          </Switch>
        </div>
      </div>
    </Router>
  );
};

【问题讨论】:

  • 您能否包含渲染PrivateRoute 的组件的整个 组件代码?您是否在PrivateRoute 中登录了一个效果挂钩isAuthenticated 以查看它是否正在接收更新的状态?您可以提供哪些尝试调试的详细信息?
  • PrivateRoute 我控制台登录isAuthenticated 看看它有什么价值。我还添加了我的 App.js 文件的外观
  • @MichaelTorres 你怎么知道 console.log 在获取用户后正在打印?或者你如何检查isAuthenticated里面的PrivateRoute
  • “在 PrivateRoute 中,我在控制台记录了 isAuthenticated 以查看它有什么价值。” 那个值是什么?你看到它在App 的状态下更新了吗?当它在App 中的状态发生变化时,你看到它更新了吗?
  • 应该,你确定 fetch 没有错误?如果 fetch 出错,setIsAuthenticated 将不会执行

标签: reactjs state


【解决方案1】:

尽量不要在传递的回调函数中使用你的道具。

像这样直接使用道具:

const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => {
  return isAuthenticated ? (
    <Route {...rest} render={(props) => <Component {...props} />} />
  ) : (
    <Route {...rest} render={(props) => <Redirect to="/login" />} />
  );
};

或者使用 useCallback 和依赖创建回调函数:

const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => {
  const component = useCallback(
    (props) => {
      isAuthenticated ? <Component {...props} /> : <Redirect to="/login" />;
    },
    [isAuthenticated]
  );
  return <Route {...rest} render={component}/>
};

【讨论】:

  • 谢谢@RobertTirta 我会记下这一点,但这并不能解决我的问题
【解决方案2】:

对于这样的问题,redux 是最好的解决方案

在您的 app.js 调度操作中设置 isAuthenticate 标志

store.dispatch(setIsAuthenticated(true))

在需要 isAuthenticate 的其他文件中,只需使用

mapStateToProps

【讨论】:

  • 谢谢,但我已经使用 redux 完成了。我试图在没有 redux 的情况下做到这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-12
  • 2015-06-11
  • 2019-08-06
相关资源
最近更新 更多