次の擬似コードの例で、Containerがfoo.barを変更してもChildが再レンダリングされないのはなぜですか。
Container {
handleEvent() {
this.props.foo.bar = 123
},
render() {
return <Child bar={this.props.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
Containerの値を変更した後にforceUpdate()
を呼び出しても、Childは古い値を表示します。
なぜなら子供たちは親の小道具が変わったとしても、そのSTATEが変わったとしても再表示しません:)
あなたが見せているのはこれです: https://facebook.github.io/react/tips/communicate-between-components.html
それは小道具を通して親から子へデータを渡すでしょうが、そこに表現の論理はありません。
何らかの状態を親に設定してから、子を親の変更状態にレンダリングする必要があります。これは助けになるかもしれません。 https://facebook.github.io/react/tips/expose-component-functions.html
属性 'key'がnameと等しくなるようにchildを更新します。
Child {
render() {
return <div key={this.props.bar}>{this.props.bar}</div>
}
}
Reactの哲学によれば、コンポーネントはその小道具を変えることができません。それらは親から受け取られるべきであり、不変であるべきです。親だけが子供の小道具を変えることができます。
state vs props についての素晴らしい説明
また、このスレッドを読んでください react.jsで小道具を更新できないのはなぜですか?
setState
関数を使うべきです。そうでない場合は、forceUpdateをどのように使用しても、stateは変更を保存しません。
Container {
handleEvent= () => { // use arrow function
//this.props.foo.bar = 123
//You should use setState to set value like this:
this.setState({foo: {bar: 123}});
};
render() {
return <Child bar={this.state.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
}
あなたのコードは無効です。このコードをテストすることはできません。
SetState関数を使用してください。だからあなたはできる
this.setState({this.state.foo.bar:123})
handleイベントメソッド内.
状態が更新されると、変更がトリガーされ、再レンダリングが行われます。
私は同じ問題を抱えていました。これは私の解決策です、私はそれが良い習慣であるかどうかわからない、そうでない場合は教えてください:
state = {
value: this.props.value
};
componentDidUpdate(prevProps) {
if(prevProps.value !== this.props.value) {
this.setState({value: this.props.value});
}
}
UPD:React Hooksを使って同じことができるようになりました:(コンポーネントが関数の場合のみ)
const [value, setValue] = useState(propName);
// This will launch only if propName value has chaged.
useEffect(() => { setValue(propName) }, [propName]);
子が状態を維持せずに単純に小道具をレンダリングしてから親から呼び出す場合は、おそらく子を機能コンポーネントとして作成する必要があります。これに代わる方法は、ステートレスコンポーネントを再レンダリングさせる機能コンポーネント(useState)でフックを使用できることです。
それらが不変であるのでまたあなたはpropasを変更するべきではありません。コンポーネントの状態を維持します。
Child = ({bar}) => (bar);