我的目标是
为了实现第二个目标,我通过以下方式使用getDerivedStateFromProps
https://codepen.io/jedgar-nawasardqn/pen/VRpWrZ?editors=1011
class Parent extends React.Component {
constructor(props) {
super(props)
this.state = {
value: "default valu"
}
}
onChange = (value) => {
this.setState({
value: value
})
}
render() {
return (
<div>
<form>
<label>Parent: </label>
<input
value={this.state.value}
onChange={(e) => this.onChange(e.target.value)}/>
</form>
<Child
value={this.state.value}/>
</div>);
}
}
class Child extends React.Component {
constructor(props) {
super(props)
this.state = {
value: this.props.value
}
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log('nextProps', nextProps)
return {
value: nextProps.value
}
}
onChange = (value) => {
console.log('CHild changed')
this.setState({
value: value
})
}
render() {
return (
<div>
<label>Child: </label>
<input
value={this.state.value}
onChange={(e) => this.onChange(e.target.value)}/>
</div>)
}
}
React.render(<Parent/>, document.getElementById('app'));
...但是由于某种原因,我无法使其正常运行。有什么建议吗?
答案 0 :(得分:2)
假设我了解您的目标,即希望在父项更改时让父项输入控制子项输入,但允许子项输入自身更改而不影响父项:
问题在于getDerivedStateFromProps
无论如何都被调用,因此当您从Child的输入更改状态时,getDerivedStateFromProps
立即将其恢复为Parent的值。您应该使用componentDidUpdate
并区分道具,而不要使用getDerivedStateFromProps
并仅在父级状态实际更改时才更新子级以匹配父级。
我根据您的小提琴制作了一个代码沙箱,以证明这一点:https://codesandbox.io/s/m5qj6qq769?fontsize=14
答案 1 :(得分:0)
首先,即使与您的问题无关,我建议您也不要在render()
方法内使用箭头功能,因此,您应该只编写{{1} }。原因是将创建箭头函数,然后在每个onChange={(e) => this.onChange(e.target.value)} />
处将其丢弃:如果渲染器和箭头函数很少,这没什么大不了的,但是最好避免浪费计算能力:)>
现在,关于您的问题!老实说,似乎onChange={this.onChange} />
组件只需要显示值,因此,将值从render()
组件“复制”到Child
组件并没有真正的作用:您可以保留您在Parent
组件中的值,然后在Child
和Parent
组件中引用该值。
为此,您还需要将处理函数传递给Parent
组件。
让我们看看小提琴吧!
Child
Child
class Child extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<label>Child: </label>
<input
value={this.props.value}
onChange={this.props.handleChange}/>
</div>
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {value: "Default Value"};
}
handleChange = (e) => {
this.setState({value: e.target.value});
}
render() {
return (
<div>
<form>
<label>Parent: </label>
<input
value={this.state.value}
onChange={this.handleChange} />
</form>
<Child
value={this.state.value}
handleChange={this.handleChange} />
</div>
);
}
}
ReactDOM.render(<Parent />, document.getElementById('root'));