I am creating a select ponent with a default value through props but suddenly when i tried to select an option, select do nothing.
I tried not to put a initial value it solve the problem but the program should not act like that.
//UserMaintenanceModal
class UserMaintenanceModal extends Component {
state = {
user_department: this.props.data.user_department,
departments: [
{id: 1, name: "IT"}, {id:2, name: "BM"}
]
}
handleChange = (event) => {
this.setState({user_department: event.target.value});
}
render(){
const { user_department } = this.state;
return (
<label>Department</label>
<select
className="form-control form-control-sm"
name='user_department'
value={user_department}
onChange={this.handleChange}
>
{
this.state.departments != null && this.state.departments.map(
department =>
<option
key = {department.id}
value = {department.name}
>
{department.name}
</option>
)
}
</select>
)
}
}
Solution
Sorry, my mistake. I did not show all of the source code. The reason it was not changing it because of this code which is inside a parent ponent.
//NavComponent
ponentWillMount() {
document.addEventListener('mousedown', this.handleClick, false);
}
ponentWillUnmount() {
document.removeEventListener('mousedown', this.handleClick, false);
}
I did get this code from here. It act to hide active dropdown nav menu when click outside of the ponent.
I am creating a select ponent with a default value through props but suddenly when i tried to select an option, select do nothing.
I tried not to put a initial value it solve the problem but the program should not act like that.
//UserMaintenanceModal
class UserMaintenanceModal extends Component {
state = {
user_department: this.props.data.user_department,
departments: [
{id: 1, name: "IT"}, {id:2, name: "BM"}
]
}
handleChange = (event) => {
this.setState({user_department: event.target.value});
}
render(){
const { user_department } = this.state;
return (
<label>Department</label>
<select
className="form-control form-control-sm"
name='user_department'
value={user_department}
onChange={this.handleChange}
>
{
this.state.departments != null && this.state.departments.map(
department =>
<option
key = {department.id}
value = {department.name}
>
{department.name}
</option>
)
}
</select>
)
}
}
Solution
Sorry, my mistake. I did not show all of the source code. The reason it was not changing it because of this code which is inside a parent ponent.
//NavComponent
ponentWillMount() {
document.addEventListener('mousedown', this.handleClick, false);
}
ponentWillUnmount() {
document.removeEventListener('mousedown', this.handleClick, false);
}
I did get this code from here. It act to hide active dropdown nav menu when click outside of the ponent.
Share Improve this question edited Feb 20, 2019 at 14:32 Adrian Manuel Cleofe asked Feb 18, 2019 at 15:24 Adrian Manuel CleofeAdrian Manuel Cleofe 453 silver badges12 bronze badges3 Answers
Reset to default 3Take a look at this CodePen I've made: https://codepen.io/Gesma94/pen/QYYWKG
Since you are taking the value from the props, it means the parent Component keeps the value in the state (probably), so, when you select an option, you need to update the state of the parent Component, and in order to do that you need an handlerFunction passed to the Component with the options from the Parent.
class List extends React.Component {
options = ["one", "two", "threee"];
render() {
const {handleChange, value} = this.props;
return (
<select value={value} onChange={handleChange}>
{
this.options.map((option, index) =>
<option key={index} value={option}>
{option}
</option>
)}
</select>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {value: "one"};
}
handleChange = (e) => {
this.setState({value: e.target.value})
}
render() {
return <List handleChange={this.handleChange} value={this.state.value} />
}
}
ReactDOM.render(<App />, document.getElementById("root"));
EDIT Ok, so.. One of the problem is what I said yesterday: you pass to the UserMaintenanceModal
Component the default value, which is saved in the state of the App
Component. But then, in UserMaintenanceModal
Component you update the state of itself, and not the state of the App
Component, so you kinda have an inconsistency.
Anyways, this is not your biggest problem: as far as I can see, there is some "confusion" (or maybe it's more probably that I don't fully understand what you want to achieve :) ). So, now I'm assuming that, as I said in the ment, you just want to display all the users belonging with the department selected!
I see that, inside the handleChange
of App
Component you save in the data
property of the state the information about the currently clicked user (I don't know if this is mandatory or it was a try to achieve what I assumed). In case you did you want to save that info, that is redundant since you already have all these information in the users
property: you could just save the userId
or the position in the users
array of the clicked user.
Then, I also don't understand why showModal
is originally set to false
and became true
when you click on a user: this way it seems all the users should be visible at start, and once you clicked on one of them you kinda filter the users by the Department to which the clicked user belongs with. But if this is the case, I don't know why the select should became visible after.. :S
Finally, in the render()
method of the App
Component you should somehow say "hei, render only the users that belongs with the department selected", which you did not attempt (as far as I can see). In the following example I'm using a filter
native function, but you could just have kept only the map
function and return the user only if its user_department
was equal to the currently selected.
Anyways, I also assumed that the selection should be visible from start, and I've forked your codepen, take a look at this and let me know if this is what you wanted: https://codepen.io/Gesma94/pen/aXXjvE
Notice that, in this example, the departments values are in the state of UserMaintenanceModal
which isn't a good thing at all: you should retrieve the departments from the users
array saved in the state of the App
Component, and then pass them to the UserMaintenanceModal
Component.. I mean, you should do something like "ok, let's see all my users and see all the departments that I have.. Ok now, that I have it, let's pass them to the UserMaintenanceModal
.
You can put the default value prop in the ponent state and continue to use that.
Example
class App extends React.Component {
state = {
options: ["foo", "bar", "baz"],
selectedOption: this.props.defaultOption
};
onChange = e => {
this.setState({ selectedOption: e.target.value });
};
render() {
const { options, selectedOption } = this.state;
return (
<select value={selectedOption} onChange={this.onChange}>
{options.map((option, index) => (
<option key={index} value={option}>
{option}
</option>
))}
</select>
);
}
}
ReactDOM.render(<App defaultOption="bar" />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Problem
In my case, I wanted to switch or render different ponents to fill based on the selected
field. Whenever I switched it, I could not be able to reset the selected fields of the rendered ponent. as a result, I could not show the right placeholder rather first option
. This wrong and could confuse users.
I added the
defaultValue
inselect
tag. This the placeholder I want a user to see for the first time
I added the
value
inselect
tag. This helped me to track whenever users changed the mind or clean the data.
<select
name={inputName}
id={inputId}
className="input-controller-required"
required
onChange={onHandleInputChange}
defaultValue={defaultValue}
value={defaultValue} // I forgot to add value
>
<option disabled value="">{placeholder}</option>
{
options.map((item, index) => (
<option value={item.value} key={index}>{item.text}</option>
))
}
</select>
Thanks, @Jolly's answer and other contributors for support.