如何正确更新React组件?子组件API请求新增属性后未渲染如何解决
问题原因
- 你没有通过React官方提供的
setState方法修改状态:React的状态不可直接修改,直接对this.state下的属性赋值不会触发组件重新渲染,所以uuid更新后界面没有响应。 - 异步请求的调用时机不对:constructor仅负责组件初始化状态,不适合执行副作用类的异步请求,这类请求应该放在
componentDidMount生命周期函数中执行,避免出现组件未挂载就更新状态的潜在报错。 - 直接修改原props传入的contract对象不符合React单向数据流规范:props是只读属性,不应该直接修改其内部属性。
解决方案
修正后的代码如下:
class Contract extends Component { constructor(props){ super(props); // 初始化状态,拷贝props传入的contract对象,提前声明uuid字段避免undefined警告 this.state = { data: { ...props.contract, uuid: '' } }; } componentDidMount() { // 组件挂载后再发起异步请求 getUuidByName(this.state.data.name).then(val => { // 调用setState触发重渲染,通过扩展运算符生成新的data对象 this.setState(prevState => ({ data: { ...prevState.data, uuid: val } })); }); } render() { return <tr> <td>{this.state.data.id}</td> <td>{this.state.data.name}</td> <td>{this.state.data.uuid || '加载中'}</td> {/* 增加加载状态提示更友好 */} </tr> } }
如果需要响应父组件传入的contract属性变更,可以补充componentDidUpdate逻辑:
componentDidUpdate(prevProps) { // 只有contract的name发生变化时才重新请求uuid if (prevProps.contract.name !== this.props.contract.name) { getUuidByName(this.props.contract.name).then(val => { this.setState({ data: { ...this.props.contract, uuid: val } }) }) } }
内容的提问来源于stack exchange,提问作者Misha
相关产品推荐
相关产品推荐

