React组件数组Prop在constructor中为空的原因及解决办法
为什么React组件constructor里数组Prop为空,render里却有值?
这个问题我碰到过好多次,本质是React组件生命周期和异步数据加载的配合问题,我给你拆解一下:
问题原因
- constructor的执行时机:
constructor是组件第一次被实例化时才会执行的方法,而且整个组件生命周期里只会跑一次。你的父组件中this.props.cities大概率是通过异步请求获取的(比如从后端接口拉取城市数据),第一次渲染父组件时,异步请求还没完成,cities是空数组,所以传给子组件的options自然也是空的,这时候constructor里打印就会是空。 - render的执行时机:当父组件的异步请求完成,
cities数据更新后,父组件会触发重新渲染,把最新的cities传给子组件。这时候子组件的render方法会重新执行,所以你能在render里拿到有值的options——但constructor不会再执行了,因为组件已经实例化过了。
解决方案
根据你需要用这个数组做的事情,有几种不同的处理方式:
1. 用生命周期钩子处理初始化和更新
如果需要在组件加载时就基于数组做初始化操作(比如给allOptions赋值),可以用componentDidMount(处理首次挂载)和componentDidUpdate(处理props更新):
import React, { Component } from "react"; import { Dropdown } from "semantic-ui-react" class SearchableDropdown extends Component { defaultOptions = [] allOptions = [] constructor(props) { super(props) console.log(props.options) // 这里是空的,属于正常情况 } componentDidMount() { // 组件挂载完成后,拿到最新的options console.log(this.props.options) this.allOptions = this.props.options } componentDidUpdate(prevProps) { // 只有当options确实变化时,才更新allOptions if (prevProps.options !== this.props.options) { this.allOptions = this.props.options } } search = (event, { searchQuery }) => { console.log(searchQuery) } render () { console.log(this.props.options) return ( <Dropdown selection search onSearchChange={this.search} {...this.props}/> ) } } export { SearchableDropdown }
2. 直接在使用时引用props
如果你的逻辑(比如搜索过滤)不需要提前缓存数组,完全可以在需要的时候直接用this.props.options,这样每次props更新后,都能拿到最新的数组:
search = (event, { searchQuery }) => { // 直接用最新的props.options做过滤 const filtered = this.props.options.filter(item => item.label.toLowerCase().includes(searchQuery.toLowerCase()) ) // 后续处理逻辑 }
3. 同步到组件state(如果需要基于数组维护内部状态)
如果需要把这个数组同步到组件自己的state里,可以在constructor初始化空state,再在生命周期里更新:
constructor(props) { super(props) this.state = { allOptions: props.options || [] } } componentDidUpdate(prevProps) { if (prevProps.options !== this.props.options) { this.setState({ allOptions: this.props.options }) } }
内容的提问来源于stack exchange,提问作者Ziyadin Shemsedinov
相关产品推荐
相关产品推荐

