[英]Updating child props on parent state change
I've parent component with state which contains task
and child which handles input that changes it's name. 我的父组件的状态包含
task
和子组件,该子组件处理更改其名称的输入。 Input uses his own name
state for inputs value. 输入使用自己的
name
状态作为输入值。 After submit
or blur
parents function is invoked to update state of parents task.name
. submit
或blur
后, submit
调用父函数来更新父task.name
状态。 In parent on componentDidUpdate()
is new state sent to the server via websocket and server sends changes to another clients. 在
componentDidUpdate()
父项中,是通过websocket发送到服务器的新状态,服务器将更改发送到另一个客户端。
My component keep value because it is in it's state but in another clients (which has just recieved new value from server) it is unchanged because value of input has been set only in componentDidMount()
. 我的组件保留值,因为它处于状态,但是在另一个客户端(刚刚从服务器接收到新值)中,它保持不变,因为仅在
componentDidMount()
设置了输入值。 How do I force new state to these child components? 如何对这些子组件强制采用新状态?
Parent 父级
componentDidMount() {
//Recieve changed data from server. This updates the state of all tasks, but doesn't invoke change of Child component because value has been set only in componentDidMount()
ioClient.on("onDataChanged", (data) => {
this.setState({tasks: data.tasks});
});
}
componentDidUpdate() {
//Sends data to server and invokes change in another clients
ioClient.emit('onDataChanged',this.state);
}
onTaskUpdate(task) {
const updatedTasks = this.state.tasks;
updatedTasks[task.id] = task;
const newState = {...this.state, tasks: updatedTasks};
this.setState(newState);
}
render() {
return (
{/* ... some code and for cycle of this.state.tasks */}
<Task key={task.id}
task={task}
onTaskUpdate={this.onTaskUpdate}
/>
{/* ... */}
);
}
Child (Task) 儿童 (任务)
constructor(props) {
super(props);
this.state = {name: ''};
this.handleInputChange = this.handleInputChange.bind(this);
this.nameFormSubmit = this.nameFormSubmit.bind(this);
}
componentDidMount() {
// component is already mounted so parents change doesn't invoke this again
this.setState({name: this.props.task.name});
}
handleInputChange(e) {
this.setState({[e.target.name]: e.target.value});
}
nameFormSubmit(e) {
e.preventDefault();
let updatedTask = {...this.props.task, name: this.state.name};
this.props.onUpdate(updatedTask);
}
render() {
return (
<form onSubmit={(e) => this.nameFormSubmit(e)}>
<input type="text"
name="name"
value={this.state.name}
onChange={this.handleInputChange}
/>
</form>
);
}
I'm using components own state because I don't want to send to server each pressed key but just final state of input. 我使用组件自己的状态,因为我不想将每个已按下的键发送给服务器,而只是发送给输入的最终状态。 Expected result: Emit/send changed inputs name only on submit, not with every change
预期结果:仅在提交时发送/发送更改的输入名称,而不是每次更改
My current solution which works but I am not happy with it because I don't think it's properly resolved. 我当前的解决方案有效,但是我不满意,因为我认为解决方法不正确。
I've used getDerivedStateFromProps
and new state focused
to indicate if state has to be replaced. 我用
getDerivedStateFromProps
和新的国家focused
来指示状态,必须更换。 Toggling the focused
state onFocus
and onBlur
. 切换
focused
状态onFocus
和onBlur
。
Updated Child component below: 下面更新了子组件:
Child (Task) 儿童 (任务)
constructor(props) {
super(props);
this.state = {
name: '',
focused: false
};
this.toggleFocusedState = this.toggleFocusedState.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.nameFormSubmit = this.nameFormSubmit.bind(this);
}
static getDerivedStateFromProps(props, state) {
return !state.focused ? {name: props.task.name} : null;
}
toggleFocusedState(state) {
this.setState({focused:state});
}
componentDidMount() {
this.setState({name: this.props.task.name});
}
handleInputChange(e) {
this.setState({[e.target.name]: e.target.value});
}
nameFormSubmit(e) {
e.preventDefault();
let updatedTask = {...this.props.task, name: this.state.name};
this.props.onUpdate(updatedTask);
}
render() {
return (
<form onSubmit={(e) => this.nameFormSubmit(e)}>
<input type="text"
name="name"
value={this.state.name}
onChange={this.handleInputChange}
onFocus={()=>this.toggleFocusedState(true)}
onBlur={()=>this.toggleFocusedState(false)}
/>
</form>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.