Reputation: 8978
I have a problem with updating component in React. My Autocomplete
component has its defaultValue
property which is linked to this.state.tags
. At the time of executing render()
method the this.state.tags
array is not yet fetched, so it's set empty in the component. When this.state.tags
array is set to it's fetched value the Autocomplete
is not updated by the React.
constructor(props) {
super(props);
this.state = {
tags:[],
all_tags:[{tag: "init"}]
};
}
componentDidMount() {
axios.post('http://localhost:1234/api/issue/getIssueById', {id: this.props.match.params.id}, { withCredentials: true })
.then(res=>{
var arr = [];
res.data.tags.forEach(x=>{
arr.push({tag: x});
});
this.setState((state,props)=>{return {tags: arr}});
})
.catch((e)=>{console.log(e)});
}
render() {
return (
<Fragment>
<Autocomplete
multiple
defaultValue={this.state.tags[0]}
onChange={(event, value) => console.log(value)}
id="tags-standard"
options={this.state.all_tags}
getOptionLabel={option => option.tag}
renderInput={params => (
<TextField
{...params}
variant="standard"
label="Multiple values"
placeholder="Favorites"
fullWidth
/>
)}
/>
</Fragment>
);
}
Edit:
If I put this inside render()
:
setTimeout(()=>{
console.log("this.state.tags: ", this.state.tags);
}, 1000);
this.state.tags
is set correctly.
Upvotes: 0
Views: 145
Reputation: 17858
First, you need to use this.state.tags
as options in Autocomplete.
Second your usage of setState seems problematic.
And lastly, if you need to populate all the tags in the render, you need to use value
property of the Autocomplete component.
import React, { Fragment, Component } from "react";
import { fetchTags } from "./fakeApi";
import Autocomplete from "@material-ui/lab/Autocomplete";
import TextField from "@material-ui/core/TextField";
class App extends Component {
constructor(props) {
super(props);
this.state = {
tags: [],
selectedTags: [],
all_tags: [{ tag: "init" }]
};
}
componentDidMount() {
fetchTags()
.then(res => {
let allTags = res.data.tags.map(el => ({ tag: el }));
this.setState({
tags: allTags,
selectedTags: allTags
});
})
.catch(e => {
console.log(e);
});
}
onChange = value => {
this.setState({
selectedTags: value
})
}
render() {
return (
<Fragment>
<Autocomplete
multiple
value={this.state.selectedTags}
onChange={(event, value) => this.onChange(value)}
id="tags-standard"
options={this.state.tags}
getOptionLabel={option => option.tag}
renderInput={params => (
<TextField
{...params}
variant="standard"
label="Multiple values"
placeholder="Favorites"
fullWidth
/>
)}
/>
</Fragment>
);
}
}
export default App;
Working Codesandbox sample with a fake api.
Upvotes: 0
Reputation: 582
You are using options={this.state.all_tags}
and in the componentDidMount
you are updating tags
field in the state. I think there is the issue.
Upvotes: 2