我正在尝试创建一个动态组件,该组件将数据索引与通过路由器获得的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>
)
}
答案 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
))