2017-05-31 6 views
2

ここでレンガの壁に当たったので、次の2つのバージョンのコードが異なる動作をする理由を完全に理解できません。最初のバージョンで動的なレンダリングコンポーネントに反応する(オブジェクト割り当てと関数の戻り)

私はthis.childComponent = (<ChildComp />)を初期化していたときに、その小道具は私が(setState()経由)Parentの状態を変更したときに更新していないようです。これは、setState()が実際に呼び出され、Parentの状態が更新されても発生します。

2番目のバージョンでは、実際にコンポーネント(this.childComponent =() => {return (<ChildComp />)})を返す関数を初期化すると、すべてが魅力的に機能し、小道具が更新されます。 私は2番目のバージョンを使用しています(動作しています)が、なぜこれが動作し、最初のバージョンが動作しないのかを理解したいと思います。

1.

class Parent extends React.Component { 
    constructor() { 
    this.state = { 
     value: 1 
    } 
    this.childComponent = (
     <Child value={this.state.value} 
     setValue={() => this.setValue()}/> 
    ) 
    } 
    setValue() { 
    this.setState({value: 2}) 
    } 
    render() { 
    return ({this.childComponent}) 
    } 
} 

2.は(this.childComponentがある:私は親コンポーネントの次の2つのバージョンを持っている

class Child extends React.Component { 
    render() { 
    return (
     <button onClick=(this.props.setValue())> 
     {this.props.value} 
     </button> 
    ) 
    } 
} 

:ここ

は、子コンポーネントです今はreact要素を返す関数)

class Parent extends React.Component { 
    constructor() { 
    this.state = { 
     value: 1 
    } 
    this.childComponent =() => { 
     return (
     <Child value={this.state.value} 
     setValue={() => this.setValue()}/> 
    ) 
    } 
    } 
    setValue() { 
    this.setState({value: 2}) 
    } 
    render() { 
    return ({this.childComponent()}) 
    } 
} 

私の問題を分かりやすくするためにコードを単純化しようとしました。

this.childComponent = (
    <Child value={this.state.value} 
    setValue={() => this.setValue()}/> 
) 

は一度だけ実行され、現在、静的な値である、コンストラクタで定義されていたので、あなたが最初のケースでリターンを持っていない、事前に

+1

最初の(壊れた)バージョンでは、子コンポーネントは静的に定義され、再度変更されることはありません。 – pscl

+1

あなたが最初のケース '(レンダリングに復帰していない){ リターン{} this.childComponent }'働くことは、そうでない子コンポーネントは、静的 –

+0

がそれを手に入れた説明のためのおかげで –

答えて

1

以下の作業スニペットを参照してくださいその内部状態に変化があります効率的にDOMを毎回更新するreconciliationと呼ばれる戦略を使用しています反応します。通常、これはsetStateコール後に発生します。あなたの最初の例で

それはconstructorに一度だけ作成していますように、Parentコンポーネント内renderメソッドは常に、同じChildコンポーネントを返します。このため、調整アルゴリズムは何も変更されていないため変更を検出しません。

<Child value={this.state.value} setValue={() => this.setValue()}/>は、React.createElement(Child, {value: this.state.value, setValue:() => this.setValue()}, null)の構文砂糖に過ぎないことを指摘したいと思います。 createElementは単にオブジェクトを返します。

2つ目の例では、すべてのrenderコールで、childComponentが呼び出され、新しいChildコンポーネントが作成されます。

1

、ありがとうございました。

これは、呼び出されるたびに実行される関数であるとして機能します。

最初のメソッドを実行する場合は、すべての変更でrenderが呼び出されるため、コンストラクタではなくレンダリングで子コンポーネントを定義します。あなたのコードにも多くの間違いがありました。

class Parent extends React.Component { 
 
    constructor() { 
 
    super(); 
 
    this.state = { 
 
     value: 1 
 
    } 
 
    
 
    } 
 
    setValue() { 
 
    this.setState({value: 2}) 
 
    } 
 
    render() { 
 
     const childComponent = (
 
     <Child value={this.state.value} 
 
     setValue={() => this.setValue()}/> 
 
    ) 
 
    return (<div>{childComponent}</div>) 
 
    } 
 
} 
 

 
class Child extends React.Component { 
 
    render() { 
 
    return (
 
     <button onClick={this.props.setValue}> 
 
     {this.props.value} 
 
     </button> 
 
    ) 
 
    } 
 
} 
 

 
ReactDOM.render(<Parent/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="app"></div>

+0

説明と作業を追加しました最初のメソッドでスニペット –

関連する問題