より最近の回答例を使用して、 React.useState
親コンポーネントで状態を維持することをお勧めします。親は、2つの子コンポーネント間で管理するため、それにアクセスできる必要があります。Reduxが管理するようなグローバル状態に移行することは、ソフトウェアエンジニアリングにおいてグローバル変数がローカルよりも一般的に悪いのと同じ理由で推奨されません。
状態が親コンポーネント内にある場合、親が子value
とonChange
ハンドラーをプロップで指定すると、子は状態を変更できます(値リンクまたは状態リンクパターンと呼ばれることもあります)。ここでは、フックを使用してそれを行う方法を示します。
function Parent() {
var [state, setState] = React.useState('initial input value');
return <>
<Child1 value={state} onChange={(v) => setState(v)} />
<Child2 value={state}>
</>
}
function Child1(props) {
return <input
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
}
function Child2(props) {
return <p>Content of the state {props.value}</p>
}
親コンポーネント全体が子の入力変更時に再レンダリングされます。これは、親コンポーネントが小さい/再レンダリングが速い場合は問題にならない可能性があります。親コンポーネントの再レンダリングのパフォーマンスは、一般的なケース(大きなフォームなど)でも問題になる可能性があります。これはあなたのケースで解決された問題です(以下を参照)。
状態リンクパターンと親の再レンダリングなしは、Hookstateのようなサードパーティライブラリを使用して実装する方が簡単です -スーパーチャージReact.useState
あなたのものを含め、ユースケースのカバー様々な。(免責事項:私はプロジェクトの作成者です)。
これがフックステートでどのように見えるかです。Child1
入力を変更し、Child2
それに反応します。Parent
のみ、状態を保持しますが、状態の変化に再表示されませんChild1
とChild2
なります。
import { useStateLink } from '@hookstate/core';
function Parent() {
var state = useStateLink('initial input value');
return <>
<Child1 state={state} />
<Child2 state={state}>
</>
}
function Child1(props) {
// to avoid parent re-render use local state,
// could use `props.state` instead of `state` below instead
var state = useStateLink(props.state)
return <input
value={state.get()}
onChange={e => state.set(e.target.value)}
/>
}
function Child2(props) {
// to avoid parent re-render use local state,
// could use `props.state` instead of `state` below instead
var state = useStateLink(props.state)
return <p>Content of the state {state.get()}</p>
}
PS:深くネストされたデータ、状態の検証、フックを使用したグローバルな状態など、類似したより複雑なシナリオをカバーする例が他にも多数ありますsetState
。フック状態と上記で説明した手法を使用する完全なサンプルアプリケーションオンラインもあります。