2017-04-09 28 views
0

これはReactへの最初の1週間です。私はトリクルダウン状態を実現するのが難しいと思っています。子コンポーネント状態が更新されていない

私がしたいこと:親コンテナがソケットからメッセージを受け取ると、親の状態変更が子要素のそれぞれに流れ込むようにします。

現在の状況:以下のコードでは、すべてのコンポーネントが画面に表示され、メッセージは受信されますが、子要素はどのタイプの更新も登録しません。

**アップデート: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

子要素でconstructorは、かつて呼ばれ、したがって、あなたの状態は、子要素で更新gettinngされていません。また、それは小道具に依存するときにコンストラクタで状態を設定する反パターンです。小道具を更新するときに呼び出されるライフサイクル機能の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} /> 
    } 
} 
+0

私はcomponentWillReceivePropsがいつでも実行されていないと思います。初期化時または親状態の変更時には使用されません。初期化時にのみ、 'componentWillUpdate'が呼び出されます。 –

+0

'componentWillReceiveProps'は最初に実行されるのではなく、そのたびに小道具が変更されます。更新された回答をお試しください –

関連する問題