gliss413
gliss413

Reputation: 21

Setting a radio button to be checked as default, only when passing in a prop in React

Suppose I have a function like this in React

function Stars({handleStarClick, starClicked}) {

    if (starClicked === 3) {
      document.getElementById('star3').checked = true
    }

    return (

    <div className="rate">
        <input onClick={() => handleStarClick(5)} type="radio" id="star5" name="rate" value="5"/>
        <label htmlFor="star5" title="text">5 stars</label>
        <input onClick={() => handleStarClick(4)}  type="radio" id="star4" name="rate" value="4" />
        <label htmlFor="star4" title="text">4 stars</label>
        <input onClick={() => handleStarClick(3)}  type="radio" id="star3" name="rate" value="3" />
        <label htmlFor="star3" title="text">3 stars</label>
        <input onClick={() => handleStarClick(2)}  type="radio" id="star2" name="rate" value="2" />
        <label htmlFor="star2" title="text">2 stars</label>
        <input onClick={() => handleStarClick(1)}  type="radio" id="star1" name="rate" value="1" />
        <label htmlFor="star1" title="text">1 star</label>
    </div>
    )
}

I want the default behavior to have all the radio buttons unchecked. However, let's say in a form a user selects the 3-star radio button, I would like to be able to pass in a prop that allows me to render this component with the 3-star radio button checked. What is the best way to go about this?

Upvotes: 2

Views: 313

Answers (1)

Amila Senadheera
Amila Senadheera

Reputation: 13245

In React you shouldn't use document.getElementById() to access DOM elements. It should be done using React Refs. In this case, you can avoid it.

You can use the following as a prop to make it work:

checked={index === starClicked}

Your code can be simplified as below:

function Stars({ handleStarClick, starClicked }) {
  return (
    <div className="rate">
      {Array.from({ length: 5 }, (_, i) => {
        const index = 5 - i;
        return (
          <React.Fragment key={index}>
            <input
              onChange={() => handleStarClick(index)}
              checked={index === starClicked}
              type="radio"
              id={`star${index}`}
              name="rate"
              value={index}
            />
            <label htmlFor={`star${index}`} title="text">
              {index} stars
            </label>
          </React.Fragment>
        );
      })}
    </div>
  );
}

function App() {
  const [starClicked, handleStarClick] = React.useState(-1);

  return <Stars handleStarClick={handleStarClick} starClicked={starClicked} />;
}

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

Upvotes: 2

Related Questions