在React子组件上使用props更新状态
Updating state with props on React child component
我有一个React应用,其中父组件中的props被传递给子组件,然后这些props设置了子组件的状态。
当我把更新后的值发送给父组件后,子组件不会用更新后的props来更新状态。
我如何让它更新子组件的状态?
我的简化代码:
class Parent extends React.Component {
constructor (props) {
super(props);
this.state = {name: ''}
}
componentDidMount () {
this.setState({name: this.props.data.name});
}
handleUpdate (updatedName) {
this.setState({name: updatedName});
}
render () {
return <Child name={this.state.name} onUpdate={this.handleUpdate.bind(this)} />
}
}
class Child extends React.Component {
constructor (props) {
super(props);
this.state = {name: ''}
}
componentDidMount () {
this.setState({name: this.props.name});
}
handleChange (e) {
this.setState({[e.target.name]: e.target.value});
}
handleUpdate () {
// ajax call that updates database with updated name and then on success calls onUpdate(updatedName)
}
render () {
console.log(this.props.name); // after update, this logs the updated name
console.log(this.state.name); // after update, this logs the initial name until I refresh the brower
return <div>
{this.state.name}
<input type="text" name="name" value={this.state.name} onChange={this.handleChange} />
<input type="button" value="Update Name" onClick={this.handleUpdate.bind(this)} />
</div>
}
}
您需要在您的孩子中实现componentWillReceiveProps
:
componentWillReceiveProps(newProps) {
this.setState({name: newProps.name});
}
编辑: componentWillReceiveProps
现在已弃用并将被删除,但在上面的文档链接中有其他建议
在componentWillReceiveProps中调用setState()
不会导致额外的重新渲染。接收道具是一个渲染和这个。如果setState在componentDidUpdate这样的方法中执行,它将是另一个渲染。我建议在shouldComponentUpdate中执行this.state.name !== nextProps.name
,以便始终检查任何更新。
componentWillReceiveProps(nextProps) {
this.setState({name: nextProps.name});
}
shouldComponentUpdate(nextProps) {
return this.state.name !== nextProps.name;
}
最好检查一下是否需要更新状态,因为这会导致重新渲染。
componentWillReceiveProps(newProps) {
if (this.state.name !== newProps.name) {
this.setState({name: newProps.name});
}
}
有几件事。至少可以这么说,在click上绑定函数的方式是不寻常的。我建议你要么在构造函数中这样做,要么使用箭头函数(这会自动将函数绑定到类)。
export default class Parent extends Component {
constructor (props) {
super(props);
this.state = {name: ''}
}
handleUpdate = (updatedName) => {
this.setState({name: updatedName})
}
render () {
return <Child name={this.state.name} onUpdate={this} />
}
}
export default class Child extends React.Component {
constructor(props) {
super(props);
this.state = { name: "" };
}
componentDidMount() {
this.setState({ name: this.props.name });
}
handleChange = (e) => {
this.setState({ name: e.target.value });
}
handleUpdate() {
// ajax call that updates database with updated name and then on success calls onUpdate(updatedName)
}
render() {
console.log(this.props.name); // after update, this logs the updated name
console.log(this.state.name); // after update, this logs the initial name until I refresh the brower
return (
<div>
{this.state.name}
<input
type="text"
name="name"
value={this.state.name}
onChange={this.handleChange}
/>
<input
type="button"
value="Update Name"
onClick={this.handleUpdate}
/>
</div>
);
}
}
此外,我建议您决定是否需要从Parent或Child管理/更新props 。如果Parent负责处理状态,那么你应该将handleUpdate传播给Parent:
//@Parent component
<Child handleUpdate={()=> this.handleUpdate} .../>
//@Child component
handleUpdate = () => {
this.props.handleUpdate
}
你不应该被要求使用任何其他函数(在React 16+中)来管理从子到父的道具,反之亦然。
通常这些"双向"的情况是结构的"气味",表明每个组件的关注点分离已经被错误地调整或者还没有完全弄清楚。
相关文章:
- Javascript循环不会自我更新
- 添加文字和评论功能更新Div
- AngularJS:ng之后,重复$scope值未按预期更新
- 如何通过数组更新角度子范围
- Ajax聊天消息重复而不仅仅是更新
- 通过CSV文件上载更新数据库表
- 平均值:无法将数据更新到数据库
- $rootScope未使用forEach进行更新
- d3基于用户选择动态更新节点
- 有条件更新d3.js力图中节点的最佳方法
- Angular:更新一次性绑定的数据
- Javascript更新孙窗口中的表单元素
- 更新道具后,这.props总是=== nextProps / prevProps
- 我可以更新React.js中的组件's props吗?
- 更新时重新渲染this.props.location.query.somequery Reactjs
- 子组件不会在setState之后使用新的props进行更新
- React Router: this.props.params在链接点击后没有更新
- 在React子组件上使用props更新状态
- 当props通过parent状态更新时,React - child不更新
- 反应:从渲染方法外部更新组件的 props,而不使用状态