繁体   English   中英

(React) 动态组件条件setstate

[英](React) dynamic component conditional setstate

我正在尝试创建一个动态组件,该组件将数据索引与我通过路由器获得的 URL 参数 blogID 匹配。

这里我有路由器参数并将道具发送到组件

<Route path='/blog/:blogId/:blogTitle' render={() => <BlogPost blogData={this.state.blogData} /> }  />     

然后在组件上我设置了初始 state 并尝试渲染与数据索引匹配的数据,但我收到组件重复调用 setstate 和无限循环的错误。

constructor(props){
        super(props);
        this.state = {
            blogId:'',
            blogTitle:'',
            blogData:[]
        }            
    }   

   render(){                  
        const { params:{ blogId, blogTitle } } = this.props.match;  

// so i map here to get the index and set the conditional to set the new state but I don't know where or how exactly        

        this.props.blogData.map((val, idx) => ( 
            idx == blogId ? 
                this.setState({blogData:val }) : null                               
        ))
        return (                          
          <div>              


           <BlogView title={this.state.blogData.title} />


          </div>
        )  
    } 

您获得无限循环的原因是在您的渲染方法中调用 setState,这会导致重新渲染,这会导致 setState,这会导致重新渲染......等等。

尝试将这部分移出渲染方法。

this.props.blogData.map((val, idx) => ( idx == blogId? this.setState({blogData:val }): null ))

您不应该在 render() function 中设置状态,原因是当您设置 state 时,组件需要重新渲染以向用户显示更新的数据,然后一次又一次地重新渲染,而是在 componentDidMount lifeCycle 方法中执行它只会运行一次

componentDidMount() {
  const { params:{ blogId, blogTitle } } = this.props.match;  
  this.props.blogData.map((val, idx) => ( 
    idx == blogId ? 
    this.setState({blogData:val }) : null                               
  ))
}

如果像这样在渲染中调用setState ,会导致无限循环。

找到blog后不需要setState ,只需在find后在BlogView中使用其title即可:

render() {                  
    const { params:{ blogId, blogTitle } } = this.props.match;        

    const blog = this.props.blogData.find((val, idx) => idx === blogId);
    return (                          
        <div>
            <BlogView title={blog.title} />
        </div>
        );  
} 

在渲染内部调用集合 state 之前添加一个条件块。 如果两个值相同,则不要调用集合 state。


   render(){                  
        const { params:{ blogId, blogTitle } } = this.props.match;  

// so i map here to get the index and set the conditional to set the new state but I don't know where or how exactly        

        this.props.blogData.map((val, idx) => ( 
            (idx == blogId && val != this.state.blogData) ? 
                this.setState({blogData:val }) : null                               
        ))
        return (                          
          <div>              


           <BlogView title={this.state.blogData.title} />


          </div>
        )  
    } 

是的,我终于做到了,

我在 componentDidMount() 上设置了 state

componentDidMount(){                        
  const { params:{ blogId, blogTitle } } = this.props.match;           
  this.setState({blogId, blogTitle});
} 

以及渲染上的比较,效果很好

const blogger =  this.props.blogData.map((val, idx) => (             
            idx == this.state.blogId ?
                <BlogView 
                    title={val.title}
                    body={parse(val.body)}
                    img={val.thumb}
                />
                : null            
        )) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM