2017-03-16 2 views
0

我々は2人の子供C1とC2との親コンポーネントで次のセットアップを持っていると仮定します。React:変数としてコンポーネントにPropとして渡された状態を代入すると、更新が妨げられますか?

Example: container for C1 and C2, with a state called data 

    -C1: input, updates state in Example through handler passed as propdisplay, shows state from Example 
    -C2: display, shows state from Example 

ここでは、コードとcodepenである:C2のコンストラクタで、我々が持っていることを

class Example extends React.Component { 
    constructor (props) { 
    super(props) 
    this.state = { data: 'test' } 
    } 

    onUpdate (data) { this.setState({ data }) } 

    render() { 
    return (
     <div> 
     <C1 onUpdate={this.onUpdate.bind(this)}/> 
     <C2 data={this.state.data}/> 
     </div> 
    ) 
    } 
} 

class C1 extends React.Component { 
    constructor(props) { 
     super(props); 
     this.onUpdate = this.props.onUpdate; 
    } 

    render() { 
     return (
     <div> 
      <input type='text' ref='myInput'/> 
      <input type='button' onClick={this.update.bind(this)} value='Update C2'/> 
     </div> 
    ) 
    } 

    update() { 
     //this.props.onUpdate(this.refs.myInput.getDOMNode().value); 
     this.onUpdate(this.refs.myInput.getDOMNode().value); 
    } 
} 

class C2 extends React.Component { 
    constructor(props) { 
     super(props); 
     this.data = this.props.data; 
    } 

    render() { 
     return <div>{this.props.data}</div> 
     //return <div>{this.data}</div> 
    } 
} 

/* 
* Render the above component into the div#app 
*/ 
React.render(<Example />, document.getElementById('app')); 

をお知らせthis.props.dataを参照してください。その変数をthis.data = this.props.dataのようなクラス属性として設定した場合、更新ボタンをクリックしてもReactがC1の更新に失敗し、Exampleのthis.state.dataが変更されました。私はthis.props.dataを直接参照する、動作する行をコメントアウトしています。

私の最初のアイデアは、Reactではこれが不正な構文でなければならないということです。しかし、C1を使ったさらなるテストでは、渡された小道具が状態ではなく関数である場合、問題はないことが示されています(C1のupdateのコードを参照してください)。

なぜ、これは小道具として渡された状態では機能しませんが、小道具として渡された機能では機能しますか?例では、C1がdataの状態を変更したと見なし、その結果、次にレンダリングするものを把握するためにthis.dataを使用するC2の再レンダリングを呼び出します。

答えて

3

は、新しい状態または小道具を取得するたびに一度だけ呼び出されるため、クラス変数は最初に渡された小道具を参照し、新しいものは参照しません。これは、コンストラクタを再度再実行しないためです。それが取り付けられていたら、それはそう

を実装する前に呼び出されconstructor

リアクトコンポーネントのコンストラクタを参照してください、それが再び呼び出されません。一方で関数、特に純粋な関数は、関数自体やその中の値を変更しなかったのでうまく動作します。

あなたが小道具に基づいて、クラス変数を更新したい場合は、それがこの使用修正するために、あなたのC2コンポーネントでshouldComponentUpdateまたはcomponentWillReceiveProps

だから、例を確認したいかもしれません変更:

componentWillReceiveProps(nextProps) { 
    this.data = this.nextProps.data 
} 

しかし、私を冗長だと思うと、ほとんどの場合、this.propsはうまく動作します。

+0

私は、小道具に基づいて状態を設定することは冗長であることに同意します。実際、反作用は、これが反パターンであることについての大きなポストを持っていました。ここにそれをうまく説明する別のスタックオーバーフローがあります。 http://stackoverflow.com/questions/28785106/reactjs-why-is-passing-the-component-initial-state-a-prop-an-anti-pattern –

関連する問題