Search code examples
javascriptreactjsuse-effect

React Select value is not resetting on State Change


I have a select component that needs to reset to the "Neutral" state after user clicks the next button. However it just continuing to show which ever the user previously selected. I have them split over the components as outlined below. You can see when the next button is pressed, the defaultValue is reset to '3', however this only seems to work for when the component first renders and never again on subsequent presses.

const QuestionLikert = ({ nextQuestion, prevQuestion, setLikertResponse, likertResponse }) => {

  return (
<div className='section'>
  <div className='container'>
    <div>
        <div>
          <select
            id='response'
            name='response'
            onChange={setLikertResponse}
            defaultValue={likertResponse}
          >
            <option value="1">Strongly Disagree</option>
            <option value="2">Disagree</option>
            <option value="3">Neutral</option>
            <option value="4">Agree</option>
            <option value="5">Strongly Agree</option>
          </select>
        </div>
      <button onClick={nextQuestion}>
        Next
      </button>
      <div>
        <span onClick={prevQuestion}>Back </span>
      </div>
    </div>
  </div>
</div>
)}

const ParentComponent = () => {

  const [currentQuestion, setCurrentQuestion] = useState(0)

  const [likertResponse, setLikertReponse] = useState('3')

  const handleLikertInput = (e) => {
    setLikertReponse(e.target.value)
  }

  const toggleNextQuestion = () => {
    setLikertReponse('3')
    setCurrentQuestion(currentQuestion + 1)
  }
  const togglePrevQuestion = () => {
    setCurrentQuestion(currentQuestion - 1)
  }

  return (
    <Layout>
      <div className='section'>
        <div className='container'>
          <div>
              <QuestionLikert 
                nextQuestion={toggleNextQuestion} 
                prevQuestion={togglePrevQuestion}
                setLikertResponse={handleLikertInput}
                likertResponse={likertResponse}
              />
          </div>
        </div>
      </div>
    </Layout>
  )
}   

Solution

  • The <select>'s value param in QuestionLikert should be controlled by the likertResponse prop, as its state comes from ParentComponent

    <select
      id='response'
      name='response'
      onChange={setLikertResponse}
      value={likertResponse}
    >
      <option value="1">Strongly Disagree</option>
      <option value="2">Disagree</option>
      <option value="3">Neutral</option>
      <option value="4">Agree</option>
      <option value="5">Strongly Agree</option>
    </select>
    

    Edit elated-leakey-gij5z