Ankzious
Ankzious

Reputation: 325

Dropdown state in React-redux

Iam trying to create a dropdown component and would like to use that selected option through out my app. The thought is when a user select a Dropdown value then, its state got save in Redux reducer then to use that value for other action. But being a beginner Iam stuck on implementation part.

Note: The dropdown wouldnt have a submit button, just the action of selecting the drop down option.

My code until this stage looks like this:

RoleDropdown.js

class RoleDropdown extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ''
        };
    }

    ...
    ...

    render() {
        return (
                <div>
                <select 
                  onChange={() => this.props.selectedRoleAction()}
                   name="roles" className="form-control">
                      <option>Select a Role</option>
                      <option value="ABC" >ABC</option>
                      <option value="DEF" >DEF</option>
                      <option value="GHI" >GHI</option>

                </select>
                <p>role is: {this.props.activeRole.value}</p>   //No value output here
                </div>
        )
    }

SelectedRoleAction.js


  const selectedRoleAction = (role) => {
    const [value, setValue] = useState("")
    setValue({ value: role.target.value })
    console.log("event from drop down is " + role)  //I cant see any logged value as well
    return {
        type: "ROLE_SELECTED",
        payload: role,
    }
};

Where Am I doing wrong? Does the "setValue" can be used in action reducers?

Upvotes: 0

Views: 2435

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42188

An action creator does not hold any local state. It is just a function that maps from some arguments to a Redux action which is an object with properties type and payload.

This is an action creator function:

const selectedRoleAction = (role) => {
    return {
        type: "ROLE_SELECTED",
        payload: role,
    }
};

In which case your component would call:

onChange={(e) => this.props.selectedRoleAction(e.target.value)}

You are trying to map from the event to the value in the action creator rather than in the component. This is unusual and I would recommend the above approach, but it's doable.

const selectedRoleEventHandler = (event) => {
    return {
        type: "ROLE_SELECTED",
        payload: event.target.value,
    }
};

In which case your component would call:

onChange={(e) => this.props.selectedRoleEventHandler(e)}

or just:

onChange={this.props.selectedRoleEventHandler}

Right now you are calling the function with no arguments this.props.selectedRoleAction() which will not work.


That just creates the action. I'm assuming that you are using the connect higher-order component so that calling this.props.selectedRoleAction will dispatch it to Redux.

The actual state is set through your Redux reducer function.


If the value is stored and updated through Redux then it should not also be in the component state.

You are dealing with a controlled component so you'll want to set the value property on your select.

I am disabling "Select a Role" and also giving it a value of the empty string "". I am using that value as a fallback if this.props.activeRole is not set.

<select
   name="roles"
   className="form-control"
   value={this.props.selectedRole || ""}
   onChange={(e) => this.props.selectedRoleAction(e.target.value)}
>
    <option value="" disabled>Select a Role</option>
    <option value="ABC">ABC</option>
    <option value="DEF">DEF</option>
    <option value="GHI">GHI</option>
</select>

Upvotes: 1

Related Questions