最近的答案有一个例子,它使用React.useState
将状态保留在父组件中是推荐的方式。父级需要访问它,因为它跨两个子组件管理它。 不建议将其移动到全局状态,就像 Redux 管理的状态一样,原因与软件工程中全局变量比本地变量差的原因相同。 p>
当状态在父组件中时,如果父在props中给子value和onChangehandler(有时称为值链接或状态链接模式)。以下是使用钩子的方法:
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>
}
整个父组件将在子组件的输入更改时重新渲染,如果父组件很小/重新渲染速度很快,这可能不是问题。在一般情况下(例如大型表单),父组件的重新渲染性能仍然可能是一个问题。在您的情况下,这是已解决的问题(见下文)。
状态链接模式和没有父级重新渲染使用 3rd 方库更容易实现,例如 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:有很多more examples here,涵盖了类似的更复杂的场景,包括深度嵌套数据、状态验证、带有setState钩子的全局状态等。还有complete sample application online,它使用了Hookstate和技术上面已经解释过了。