React select onChange not changing selected value
Solution 1
You can use componentDidUpdate() to check if incoming props are different:
componentDidUpdate(nextProps) {
if (nextProps.agent.team !== this.props.agent.team) {
this.setState({ selectedTeam: nextProps.agent.team })
}
}
In componentDidUpdate, nextProps
represents the incoming props. This will check if they are different, and the setState will ensure the component re-renders.
Additionally, this will run when the component first receives props, meaning you shouldn't have to set the default value in state.
Note: You are mixing methods, by using querySelector
to get the value of the select menu. Ideally, you would use the value in state - that way you can ensure that you are setting and getting the right value, rather than mixing methods and possibly getting the non-updated version.
Solution 2
Need to tell React to trigger the function onClick
onClick={() => this.handleOnClick()} <-----
Just a side note to help save on code, you can also use ES6 to bind functions to this
by doing an arrow function. It's not 100% for sure if it will be there in the future, but it's widely used so I think they will adopt it.
handleOnClick = () => {
const selectedTeam = document.querySelector('.team-selection').value
axios.post( ...ajax stuff... )
}
Related videos on Youtube
ryanpitts1
Updated on June 04, 2022Comments
-
ryanpitts1 almost 2 years
I have a React component that has some html rendered and part of the html is a select element. The below code works for displaying the default value of the initial select element and changes the selected value when you choose another one.
My problem is that i have a list of people and when you click on one the values on the section of the page where this is used get updated to that person's values (name, email, etc). Those all update correctly i believe because
this.props.agent
gets updated. I don't have insight into that code at the moment. My question is that the select element isn't respecting the change inthis.props.agent
and thus re-selecting the correct saved value forteam
. I'm sure usingstate
withinconstructor()
isn't the right approach.I am new to React so pardon me if my question isn't accurate or explained well enough. But how can i get it to update the pre-selected select option when
this.props.agent
updates?import React from 'react' import axios from 'axios' export class AgentTeam extends React.Component { constructor(props) { super(props) this.state = { teams: [], selectedTeam: this.props.agent.team || '' } this.handleOnClick = this.handleOnClick.bind(this) this.handleOnChange = this.handleOnChange.bind(this) } componentDidMount() { axios.get( ... ajax setup ... ).then(response => { this.setState({ teams: response.data, }) }).catch(error => { throw error }) } handleOnClick() { const selectedTeam = document.querySelector('.team-selection').value axios.post( ...ajax stuff... ) } handleOnChange = (event) => { this.setState({ selectedTeam: event.target.value }) } render() { const teamList = this.state.teams.map((team, i) => <option value={team.team_name} key={i}> {team.team_name} </option> ) return ( <div> <div className='agent-team-heading'> <span>Team</span> </div> <div className='agent-team-selector'> <select className='team-selection' value={this.state.selectedTeam} onChange={this.handleOnChange}> <option value=''>Assign Team</option> {teamList} </select> <button className="agent-team-button" onClick={this.handleOnClick}> <span>SAVE</span> </button> </div> </div> ) } }
-
varoons over 5 yearsMissing parenthesis onClick={() => this.handleOnClick()}
-
ryanpitts1 over 5 yearsSo, you're suggesting to save the state of the whole agent instead of just the team?
-
Toby over 5 yearsWell, I guess I don't really know what is in
agent
- if it's a complex object then you'd have to do some deeper checking. Ideally it should be a simple check for something that has changed. But it looks like the data from the API is the teams, so if something in props is changing then you need a method in componentDidUpdate to decide when to re-render - in this case, setting state will force the re-render. -
Toby over 5 yearsI've updated the answer to what (I think) may be a more simple check. For a more accurate answer, you could try recreating at CodeSandbox.
-
ryanpitts1 over 5 yearsThis seems to give me what i'm looking for, however, the results i get seem backwards from what i would expect.
nextProps.agent.team
is showing the team for the agent that was previously selected. Andthis.props.agent.team
is showing the team for the newly selected agent. -
Toby over 5 yearsIt's tough to say without being more familiar with the data - if you console.log inside the render() function, you should see it update multiple times as the component mounts, renders and rerenders as props and state updates.