使用示例的最新答案,该示例使用 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>
}
整个父组件将在子代中的输入更改时重新呈现,如果父组件较小/快速重新呈现,则可能不成问题。在一般情况下(例如大型表单),父组件的重新渲染性能仍然可能是个问题。根据您的情况,这已解决问题(请参阅下文)。
链路状态模式和无父重新渲染更容易使用第三方库,如实行钩键状态 -增压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和上述技术。