ReactJS Props 未在 componentWillMount() 和 componentDidMount() 中加载

ReactJS Props are not loaded in componentWillMount() and componentDidMount()

我的 React-Select 集成有以下代码,需要在首次渲染前设置一次 selectedOption 字段。

import React from 'react';
import Select from 'react-select';
 
interface IOption{
    value:string,
    label:string
}

interface Props{
    data : IOption[],
    onSelected : (id:string) => void
}

export default class ReactSelect extends React.Component<Props> {
    constructor(props){
        super(props)
        console.log("data from constructor : ",this.props.data)
    }

    tempSelectedOption:IOption | undefined
    state = {
        selectedOption:this.tempSelectedOption,
    };  

    componentWillMount(){
        this.setState({ selectedOption : this.props.data[0]},()=>{console.log("component will mount meth:",this.state.selectedOption)})
        console.log("data from componentWillMount : ", this.props.data)
    }

    componentDidMount(){
        this.setState({ selectedOption : this.props.data[0]},()=>{console.log("component did mount meth:",this.state.selectedOption)})
        console.log("data from componentDidMount : ", this.props.data)
    }

    handleChange = selectedOption => {
        this.setState({ selectedOption });
        this.props.onSelected(selectedOption.value)
        console.log(`Option selected:`, selectedOption);
    };

    render() {
        const{ selectedOption } = this.state;
        console.log("props.data in render :",this.props.data)

        return (
            <Select
                value = {selectedOption}
                onChange = {this.handleChange}
                options = {this.props.data}
            />
        );
    }
}

还有一些控制台输出

data from constructor : Array [] 
data from componentWillMount : Array [] 
props.data in render :  Array [] 
data from constructor :   Array [] 
data from componentWillMount : Array [] 
props.data in render :  Array [] 
data from constructor :   Array [] 
data from componentWillMount :   Array [] 
props.data in render : Array [] 
data from componentDidMount : Array [] 
data from componentDidMount : Array [] 
data from componentDidMount : Array [] 
props.data in render :  Array [ {…} ] 
props.data in render :  Array [] 
props.data in render :  Array [ {…} ] 
props.data in render :  Array [ {…} ] 
props.data in render :  Array [ {…} ] 
props.data in render :  Array [ {…} ] 
props.data in render :  Array [ {…} ] 
props.data in render :  Array [ {…} ] 
props.data in render :  Array [ {…}, {…} ] 
props.data in render :  Array [ {…} ] 

再见,我不是 typescript 爱好者,但我认为你的问题可能与你如何将 props 传递给 ReactSelect 组件有关。

我做了这个(非常愚蠢)example 道具记录似乎有效:

App 组件中:

...
<Child data={"ciao"} />
...

然后 Child 分量:

class Child extends React.Component<{}> {
  constructor(props) {
    super(props);
    console.log("data from constructor : ",this.props.data)
  }

  componentDidMount() {
    console.log("data from componentDidMount : ", this.props.data);
  }

  private handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    const type: string = event.currentTarget.title;

    this.setState(({ count }) => ({
      count: type === "decrement" ? count - 1 : count + 1
    }));
  };

  public render() {
    console.log("props.data in render :", this.props.data);
    return (
      ...
    );
  }
}

并且日志显示:

data from constructor :  ciao 
props.data in render : ciao 
data from componentDidMount :  ciao 

首先感谢关注问题的各位

正如我对@GiovanniEsposito 的回答所评论的那样,情况大致如下,

在父组件中涉及一个 sdk,问题是我想将数据 [0] 呈现为默认值,但是 props.data 在 componentWillMount componentDidMount 之后加载。实际上,即使在第一次渲染函数调用之后,sdk 服务调用也会返回,因此当更新 props.data 时,需要额外的渲染方法。然后 props.data 仅在 render 函数中可用,所以我不得不在 render 函数中处理问题。

我修改了render()为,

state = {
    selectedOption:null,
    propsLoaded:false
};  

render() {
    if(this.state.propsLoaded == false && this.props.data[0] != undefined){
        this.setState({ 
            selectedOption : this.props.data[0],
            propsLoaded : true
        })
    }
       
    return (
        <Select
            value = {this.state.selectedOption}
            onChange = {this.handleChange}
            options = {this.props.data}
        />
    );
}

结果我解决了我的问题,但我有一个警告,现在对我来说似乎并不严重。如果我做错了什么请警告我:)

Warning: Cannot update during an existing state transition (such as within `render`). 
Render methods should be a pure function of props and state.