Reputation: 1422
I have this piece of code that calls a web service and displays the names coming from that WS into a Dropdown component from Material UI,
What I want to do is to set the default value of the dropdown with the first element coming from the WS and also be able to select any of the options in dropdown, I read something about "State" but don't get it really good at a code level.
I'm new to React and learning by myself but some help would be nice.
import React, { Component } from 'react';
import DropDownMenu from 'material-ui/DropDownMenu';
import MenuItem from 'material-ui/MenuItem';
export default class WebserviceTest extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
this.renderOptions = this.renderOptions.bind(this);
}
componentDidMount() {
const url = 'https://randomuser.me/api/?results=4';
fetch(url)
.then(Response => Response.json())
.then(findResponse => {
console.log(findResponse);
this.setState({
data: findResponse.results
});
});
}
//will set wahtever item the user selects in the dropdown
handleChange(event, index, value) {this.setState({ value });}
//we are creating the options to be displayed
renderOptions() {
return this.state.data.map((dt, i) => {
return (
<div key={i}>
<MenuItem
label="Select a description"
value={dt.name.first}
primaryText={dt.name.first} />
</div>
);
});
}
render() {
return (
<div>
<DropDownMenu value={this.state.name} onChange={this.handleChange}>
{this.renderOptions()}
</DropDownMenu>
</div>
);
}
}
Thanks in advance.
Regards.
Upvotes: 2
Views: 13464
Reputation: 387
You need to set state of selected dropdown option. And set first value of data as selected value.
componentDidMount() {
const url = 'https://randomuser.me/api/?results=4';
fetch(url)
.then(Response => Response.json())
.then(findResponse => {
console.log(findResponse);
this.setState({
data: findResponse.results,
selected: findResponse.results[0].name.first // need to be sure it's exist
});
});
}
handleChange(event, index, value) {this.setState({ selected: value });}
.
.
.
render() {
return (
<div>
<DropDownMenu value={this.state.selected} onChange={this.handleChange}>
{this.renderOptions()}
</DropDownMenu>
</div>
);
}
UPDATED CODE
import React, { Component } from 'react';
import DropDownMenu from 'material-ui/DropDownMenu';
import MenuItem from 'material-ui/MenuItem';
export default class WebserviceTest extends Component {
constructor() {
super();
this.state = {
data: [],
selected: '',
};
this.renderOptions = this.renderOptions.bind(this);
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
const url = 'https://randomuser.me/api/?results=4';
fetch(url)
.then(Response => Response.json())
.then(findResponse => {
console.log(findResponse);
console.log(findResponse.results[0].name.first);
this.setState({
data: findResponse.results,
selected: findResponse.results[0].name.first // need to be sure it's exist
});
});
}
handleChange(value) {this.setState({ selected: value });}
//we are creating the options to be displayed
renderOptions() {
return this.state.data.map((dt, i) => {
return (
<div key={i}>
<MenuItem
value={dt.name.first}
primaryText={dt.name.first} />
</div>
);
});
}
render() {
return (
<div>
<DropDownMenu value={this.state.selected} onChange={this.handleChange}>
{this.renderOptions()}
</DropDownMenu>
</div>
);
}
}
Upvotes: 2
Reputation: 7545
this.setState
controls the variable this.state
in a special way. Whenever you use this.setState
it will run render
again to check for changes accordingly. Your dynamic content that you want to be responsive should be placed in this.state
and those should be shown in your render
function.
There are many ways to go about solving your question, but the most important principle to use is to place what you currently want to render (or the id/index number) in this.state
and use this.setState
to change it as needed.
value={this.state.name}
should be a single value from your data structure that you return from your fetch
, assuming this is what is shown on the screen.
Also, you forgot to bind
this.handleChange
in your constructor.
Stating props
in your constructor is perfectly fine to do. You only do that when you want to use something from this.props
in your constructor. You aren't, so it's perfectly safe to leave it as constructor()
and super()
Upvotes: 1