这是我进入React的第一周。我发现涓滴状态的实现是难以捉摸的。
我想要发生的事情:当父容器从套接字收到消息时,我希望父级的状态更改向下逐渐渗透到每个子元素。
当前正在发生的事情:使用下面的代码将所有组件呈现到屏幕上,接收消息,但子元素不会注册任何类型的更新。
**更新:如果我不将ProgressBlock
循环到数组中,然后将该数组放在带有{this.state.blocks}
的渲染树中,则一切正常。这是不幸的,因为它不是动态的,但至少有进展。
父容器
class InstanceContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
id: ids.pop(),
callInProgress: false,
callsCompleted: 0,
eventProgress: 0,
blocks: []
}
}
componentWillMount() {
const lightColors = ['white', 'white', 'cyan', 'green', 'green', 'yellow', 'orange', 'magenta', 'red']
for (let i = 0; i < 10; i++) {
this.state.blocks.push(<ProgressBlock bgColor={lightColors[i]} eventPlace={i} eventProgress={this.state.eventProgress} />)
}
}
render() {
socket.on(this.state.id, (msg) => {
console.log(msg)
console.log('RECEIVED MESSAGE')
console.log(this.state.id)
if (msg) {
this.setState((prevState) => ({
eventProgress: 0,
callsCompleted: prevState.callsCompleted + 1
}))
} else {
this.setState((prevState) => ({
eventProgress: prevState.eventProgress + 1
}))
}
console.log(this.state.eventProgress)
})
return (
<div className="instance-container" id={this.state.id}>
{this.state.blocks}
<CompletionCounter callsCompleted={this.state.callsCompleted} />
<DisplayLog />
<VenueName />
</div>
)
}
}
子元素
class ProgressBlock extends React.Component {
constructor(props) {
super(props)
this.state = {
light: false,
eventProgress: this.props.eventProgress,
bgColor: this.props.bgColor
}
}
componentWillUpdate() {
if (this.state.eventProgress >= this.props.eventPlace) {
this.setState({
light: true
})
}
}
render() {
console.log(this.state.eventProgress) // Does not log when parent changed
console.log(this.props.eventPlace) // Does not log when parent changed
const styleObj = {
backgroundColor: '#232323'
}
if (this.light) {
const styleObj = {
backgroundColor: this.props.bgColor
}
}
return <div className="progress-block" style={styleObj} />
}
}
答案 0 :(得分:0)
子元素中的constructor
被调用一次,因此您的状态不会在子元素中更新。它也是一个反模式,它在构造函数中依赖于props时设置状态。您应该在更新道具时调用的componentWillReceiveProps
生命周期函数中执行此操作。请参阅以下代码
class ProgressBlock extends React.Component {
constructor(props) {
super(props)
this.state = {
light: false,
eventProgress: '',
bgColor: ''
}
}
componentWillMount() {
this.setState({eventProgress: this.props.eventProgress, bgColor: this.props.bgColor});
}
componentWillReceiveProps(nextProps) {
this.setState({eventProgress: nextProps.eventProgress, bgColor: nextProps.bgColor});
}
componentWillUpdate() {
if (this.state.eventProgress >= this.props.eventPlace) {
this.setState({
light: true
})
}
}
render() {
console.log(this.state.eventProgress)
console.log(this.props.eventPlace)
const styleObj = {
backgroundColor: '#232323'
}
if (this.light) {
const styleObj = {
backgroundColor: this.props.bgColor
}
}
return <div className="progress-block" style={styleObj} />
}
}