Більш свіжа відповідь із прикладом, який використовує React.useState
Збереження стану в батьківському компоненті є рекомендованим способом. Батько повинен мати доступ до нього, оскільки він управляє ним через два дочірні компоненти. Переміщення його в глобальний стан, як і той, яким керує 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
для покриття різних випадків використання, включаючи вашу. (Відмова: Я є автором проекту).
Ось як це виглядатиме з Hookstate. 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
гаком тощо. В Інтернеті також є повне додаткове зразкове додаток , яке використовує Hookstate та методику, пояснену вище.