I have the following code for my React-Select integration and need to set the selectedOption
field for once before first render.
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}
/>
);
}
}
And here some console outputs
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 [ {…} ]
First of all, I want to thank everyone who paid attention to the question.
As I also commented to @GiovanniEsposito's answer, the situation is pretty much as follows,
In parent component a sdk is involved and the problem is I want to render data[0] as default value but, props.data is loaded after componentWillMount
componentDidMount
. Actually the sdk service call is returned even after first render function calling, so when the props.data are updated an additional render method is required. Then props.data
is become available just in render
function, so I had to handle the problem in the render
function.
I modified render()
as,
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}
/>
);
}
As a result I solved my problem but I have a warning which seems not serious for me by now. If I am doing something very wrong please warn me :)
Warning: Cannot update during an existing state transition (such as within `render`).
Render methods should be a pure function of props and state.