class Select extends React.PureComponent {
constructor(props) {
super(props)
this.state = { value: this.props.defaultValue }
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
e.persist()
if (typeof this.props.onDataChange !== 'undefined') {
this.setState({ value: e.target.value }, () => this.props.onDataChange(e))
} else {
this.setState({ value: e.target.value })
}
}
render() {
const { options } = this.props
return (
<div>
<select
value={this.state.value}
onChange={this.handleChange}
>
{options.map((option, i) => {
const value = option.value || option.path || null
const label = option.label || option.name || option
return (
<option key={`option-${i}`} value={value}>
{label}
</option>
)
})}
</select>
</div>
)
}
}
class Display extends React.PureComponent {
constructor(props) {
super(props)
}
async getSomeValues() {
try {
this.setState({ isReady: false })
await Axios.get(`some-values`)
.then(async (result) => {
this.setState({
values: result.data.values,
default: result.data.default
})
})
} catch (error) {
console.log(error)
} finally {
this.setState({ isReady: true })
}
}
componentDidMount() {
this.getSomeValues()
}
render() {
return (
<Select
options={this.state.values}
defaultValue = {this.state.defaultValue}
/>
)
}
}
I'm trying to solve what i believe to be a pretty simple problem. I have a parent component that houses a child component which is rending a select dropdown.
My parent makes a call to an API service and pulls back a list of items that are to be displayed in the select dropdown. My API returns the set of options to be displayed and an initial value to be selected on load.
The initial render takes the defaultValue property and sets the state to be displayed in the initial instance in the select component constructor, the problem i have with this, is that the api call is done after the initial render so the default value always comes out being null.
I need a mechanism to set the value of the select dropdown to an initial value on load but it has to be done as a result of the api call that happens once the component has loaded?
What is the cleanest way to set the state value to whatever is returned from the API on initial load?
I'm sure this must be an easy problem to solve but i keep getting stuck between what i want to do and the load / render patterns in react.
Any help would be appreciated.
To set a default value for an input element in React: Pass the default value as a parameter to the useState hook for controlled fields. Set the defaultValue prop on uncontrolled input fields.
You can clear the value of react select using the ref. Just store the value in the state, and change the state programmatically using componentDidUpdate etc... Note: 'value' should be an object. A simple option would be to pass null to the value prop.
The default value of the select element can be set by using the 'selected' attribute on the required option. This is a boolean attribute. The option that is having the 'selected' attribute will be displayed by default on the dropdown list.
I see two options:
Option 1
You can prevent the rendering of your Select
component until the request is finished. This will mean your constructor will fire after you have the data and will be initialized correctly.
render() {
if (this.state.defaultValue) {
return (
<Select
options={this.state.values}
defaultValue={this.state.defaultValue}
/>
)
} else {
return null; // or loading graphic
}
}
Option 2
In your Select
component, use a lifecycle method like componentDidUpdate
to check if the defaultValue
prop has changed from the last render. If so, set the default value in state. This will make it so that defaultValue
only gets set once.
componentDidUpdate(prevProps) {
if (this.props.defaultValue !== prevProps.defaultValue) {
this.setState({ defaultValue: this.props.defaultValue });
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With