Javascript React-在渲染中更新内容的正确方法

Javascript React-在渲染中更新内容的正确方法,javascript,reactjs,Javascript,Reactjs,通常我对ReactJS和呈现动态内容的原理非常有信心。不过,我确实需要一些帮助 问题开始于我有一个名为Feed的页面。此提要应显示从API获取的图像列表 我需要通过作为头传递的令牌来保护此API 在App.js中,下面是代码的相关部分,用于检查用户是否已登录并限制对提要的访问,除非他们已登录。令牌保存为state,并作为道具传递到提要中 authenticate = () => { const token = localStorage.getItem("token");

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

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

我需要通过作为头传递的令牌来保护此API

在App.js中,下面是代码的相关部分,用于检查用户是否已登录并限制对提要的访问,除非他们已登录。令牌保存为state,并作为道具传递到提要中

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>
            );
        }
authenticate=()=>{
const token=localStorage.getItem(“token”);
validateToken(令牌)
.然后(()=>{
this.setState({authenticated:true,token:token});
})
.catch(()=>{
this.setState({authenticated:false,token:false});
})
}
render(){
让privateRoutes=null;
if(this.state.authenticated){
私家路=(
{
返回(
)}} />    
{
返回(
)}} />         
);
}
在Feed中,我然后调用API来获取传入该令牌的图像。这里是问题所在,在Feed中,当我控制台记录'this.props.token'时,它在从app.js发送之前的一瞬间是空的

这意味着我无法调用componentDidMount中的API,因为令牌最初为null。此外,这意味着此时无法设置帖子的状态,因为我在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
                        )
                    })}
render(){
const token=this.props.token;
let posts=[];//应该由以下人员更新
如果(令牌!==false){
loadFeedForUser(令牌)。然后((响应)=>{
职位=回应;
console.log(posts);//成功记录
})
.catch(()=>{
员额=[];
})
}
报税表(
{Object.values(posts.map)((post,i)=>{
控制台日志(post);
返回(
//这不会在posts仍然为空数组时运行
)
})}
在HTML中,对象for循环永远不会运行,因为posts数组是空的,因为它没有注册为被API更新

我的建筑有什么问题吗?感觉一点都不好

谢谢


有人能告诉我哪里可以改进吗?我只需要在经过身份验证后从app.js传递令牌,然后获取所有图像。

在道具准备好之前组件就已经安装好了。这是一种非常常见的情况,这也是我喜欢挂钩的一个重要原因。要修复它,你应该使用
组件diddupdate
生命周期方法d、 差不多

componentDidUpdate(prevProps, prevState, snapshot) {
  if (props.token && props.token !== prevProps.token) {
    makeApiCall(props.token)
  }
}
您还需要在
componentDidMount
中具有类似的逻辑,以防它在装载期间具有令牌值。否则它不会进行初始调用

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

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

你试过componentDidUpdate吗?你真的需要
authenticated
标志吗?
token
还不够吗?另外,你不应该在
render
中执行副作用。请看。最坏的情况下,你可以使用
componentDidUpdate
方法。是的,我注意到我自己,token可以。我会尝试componentDidUpdate。我知道现在我不应该在render中这样做,但我没有选择,因为令牌最初是以null的形式出现的。