(React)动态组件条件设置状态

时间:2019-09-24 07:44:28

标签: javascript reactjs react-router

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

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

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

然后在组件上设置初始状态,并尝试呈现与数据索引匹配的数据,但是遇到组件重复调用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>
        )  
    } 

5 个答案:

答案 0 :(得分:2)

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

尝试将这部分移出render方法。

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

答案 1 :(得分:1)

您不应该在render()函数中使用setState,原因是当您设置状态时,compoennt需要重新渲染以向用户显示更新的数据,然后一次又一次地重新渲染,而应在componentDidMount lifeCycle中进行方法,使其只能运行一次

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

答案 2 :(得分:0)

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

找到setState后,您无需blog,只需在title之后在BlogView中使用其find

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>
        );  
} 

答案 3 :(得分:0)

在渲染器内部调用set状态之前添加条件块。如果两个值相同,则不要调用设置状态。


   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>
        )  
    } 

答案 4 :(得分:0)

是的,我终于做到了,

我在componentDidMount()上设置状态

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            
        ))