devYuraKim / react

udemy - jonas schmedtmann
0 stars 0 forks source link

Re10-react-quiz > src > components > Options.js | onClick Behavior Not Limited to Individual Button #14

Closed devYuraKim closed 1 week ago

devYuraKim commented 1 week ago

I expected the onClick result to affect only the clicked button, but it's actually affecting the entire set of buttons.

function Options({ question }) {
  const [result, setResult] = useState("");

  return (
    <div className="options">
      {question.options.map((option, i) => (
        <button
          className={`btn btn-option ${result}`}
          key={i}
          onClick={() =>
            i === question.correctOption
              ? setResult("correct")
              : setResult("wrong")
          }
        >
          {option}
        </button>
      ))}
    </div>
  );
}
Screenshot 2024-09-05 at 2 00 59 PM Screenshot 2024-09-05 at 2 00 54 PM
devYuraKim commented 1 week ago

When a button is clicked, change the color of all buttons based on whether they are the correct option.

function Options({ question }) {
  const [selectedOption, setSelectedOption] = useState(null);

  return (
    <div className="options">
      {question.options.map((option, i) => (
        <button
          className={`btn btn-option ${
            selectedOption !== null
              ? i === question.correctOption
                ? "correct"
                : "wrong"
              : ""
          }`}
          key={i}
          onClick={() => {
            setSelectedOption(i);
          }}
        >
          {option}
        </button>
      ))}
    </div>
  );
}
devYuraKim commented 1 week ago

When a button is clicked, only change the color of the button clicked, leaving the other buttons unchanged

function Options({ question }) {
  const [selectedOption, setSelectedOption] = useState(null);

  return (
    <div className="options">
      {question.options.map((option, i) => (
        <button
          className={`btn btn-option ${
            selectedOption === i
              ? i === question.correctOption
                ? "correct"
                : "wrong"
              : ""
          }`}
          key={i}
          onClick={() => {
            setSelectedOption(i);
          }}
        >
          {option}
        </button>
      ))}
    </div>
  );
}
devYuraKim commented 1 week ago

Key Differences

Code1 - All Buttons Change Color Based on Correct Option After Any Click

const [result, setResult] = useState("");
<button
          className={`btn btn-option ${result}`}
          key={i}
          onClick={() =>
            i === question.correctOption
              ? setResult("correct")
              : setResult("wrong")
          }
        >

Code2 - All Buttons Show Correct/Wrong Status After One Click

const [selectedOption, setSelectedOption] = useState(null);
<button
   className={`btn btn-option ${
            selectedOption !== null
              ? i === question.correctOption
                ? "correct"
                : "wrong"
              : ""
          }`}
          key={i}
          onClick={() => {
            setSelectedOption(i);
          }}
        >

Code3 - Only the Clicked Button Shows Correct/Wrong Status

const [selectedOption, setSelectedOption] = useState(null);
<button
          className={`btn btn-option ${
            selectedOption === i
              ? i === question.correctOption
                ? "correct"
                : "wrong"
              : ""
          }`}
          key={i}
          onClick={() => {
            setSelectedOption(i);
          }}
        >

1. State Management:

2. Button Styling Behavior:

3. Effect of Button Click:

devYuraKim commented 1 week ago

Final: All states controlled by reducer function in App component

  1. Removed internal state from the Options component.
  2. Added answer state management in the App component.
  3. Passed answer state as a prop to the Options component.
function Options({ question, dispatch, answer }) {
  const hasAnswered = answer !== null;

  return (
    <div className="options">
      {question.options.map((option, i) => (
        <button
          className={`btn btn-option ${i === answer ? "answer" : ""} ${
            hasAnswered
              ? i === question.correctOption
                ? "correct"
                : "wrong"
              : ""
          }`}
          key={I}
          disabled={hasAnswered}
          onClick={() => {
            dispatch({ type: "newAnswer", payload: i });
          }}
        >
          {option}
        </button>
      ))}
    </div>
  );
}

export default Options;