javascript - React - 更新渲染内容的正确方法

标签 javascript reactjs

通常我对 ReactJS 和渲染动态内容的原理非常有信心。不过,我确实需要一些帮助。

问题始于我有一个名为 Feed 的页面。此 Feed 应显示从 API 获取的图像列表。

我需要通过作为 header 传递的 token 来保护此 API。

在 App.js 中,以下是代码的相关部分,用于检查用户是否已登录并限制对 feed 的访问,除非用户已登录。 token 被保存到状态并作为 Prop 传递到 Feed 中。

authenticate = () => {
      const token = localStorage.getItem("token");
      validateToken(token)
      .then(() => {
        this.setState({ authenticated: true, token: token  });
      })
      .catch(() => {
        this.setState({ authenticated: false, token: false });
      })
  }

  render() {
        let privateRoutes = null;
        if (this.state.authenticated) {
            privateRoutes =(
                <div>

                    <Route exact path="/feed" 
                    render={(props)=>{
                        return (
                        <Feed token={this.state.token}/>)}} />    

                     <Route exact path="/profile/:username" 
                        render={(props)=>{
                          return (
                           <Profile data={props}/>)}} />         
                </div>
            );
        }

然后,在 Feed 中,我调用 API 来获取传入此 token 的图像。问题就在这里,在 Feed 中,当我控制台记录“this.props.token”时,它在从 app.js 发送的内容之前瞬间为空。

这意味着我无法调用 componentDidMount 中的 API,因为 token 最初为空。此外,这意味着我此时无法设置帖子的状态,因为我在 render() 中。

这里是提要代码:

    render() {
        const token = this.props.token;
        let posts = []; // should be updated by below
        if (token !== false) {
            loadFeedForUser(token).then((response) => {
                posts = response;
                console.log(posts); // logs successfully
            })
            .catch(() => {
                posts = [];
            })
        }
        return ( 
            <div className="App">

                <div className="content">
                    <div className="feed">
                    { Object.values(posts).map((post, i) => {
                        console.log(post);
                        return (
                            <Post/> // This does not run as posts still empty array
                        )
                    })}

在 HTML 中,for 循环对象永远不会运行,因为 posts 数组为空,因为它尚未注册为由 API 更新。

我的架构有什么问题吗?感觉不太好。

谢谢。

有人可以建议我可以在哪里改进吗?仅当经过身份验证时,我才需要从 app.js 传递 token ,然后获取所有图像。

最佳答案

在 Prop 准备好之前,组件正在安装。这是一个很常见的场景,这也是我更喜欢 hooks 的一个重要原因。要修复它,您应该使用 componentDidUpdate 生命周期方法,例如

componentDidUpdate(prevProps, prevState, snapshot) {
  if (props.token && props.token !== prevProps.token) {
    makeApiCall(props.token)
  }
}

您还需要在 componentDidMount 中具有类似的逻辑,以防它在挂载期间确实具有 token 值。否则它不会进行初始调用。

作为一个钩子(Hook),这就是需要的所有代码:

useEffect(() => {
   makeApiCall(props.token)
}, [props.token])

关于javascript - React - 更新渲染内容的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57611220/

相关文章:

javascript - 如何将我的 mapDispatchToProps 连接到 onClick Prop ?

javascript - react Hook useCallback 没有依赖

javascript - 列出所有单击的图像按钮更改图像

javascript - 单击后删除按钮

css - Styled 组件样式在 Chrome DevTools 中被禁用

javascript - 无法让 Jest 和 enzyme 从我的 App.js 渲染 div 测试

javascript - 如何在功能组件中使用 React Typescript 键入任何参数

javascript - 在 React JS 中,在哪里对更改的子属性进行操作

javascript - 从 JQuery 对象中选择 DOM 元素?

javascript - 当我点击一个链接时,只是试图显示和提醒