reactjsreact-statetwo-way-binding

What is two way binding in React?


I've been going through a React online course and they have been talking about two way binding. From the examples we've been going through, the way we implemented two way binding was that we would have some state variable in our component, and whenever we inputted some in the input bar, we would update the state value and then update the value prop within the input component

export default function Player({
  initialName,
  symbol,
  isActive,
  onPlayerNameChange,
}) {
  const [isEditing, setIsEditing] = useState(false);
  const [playerName, setPlayerName] = useState(initialName);

  function clickHandler() {
    setIsEditing((editing) => !editing);
    if (isEditing) {
      onPlayerNameChange(symbol, playerName);
    }
  }

  function handleChange(event) {
    setPlayerName(event.target.value);
  }

  return (
    <li className={isActive ? "active" : undefined}>
      <span className="player">
        {isEditing ? (
          <input
            type="text"
            required
            value={playerName}
            onChange={handleChange}
          />
        ) : (
          <span className="player-name">{playerName}</span>
        )}

        <span className="player-symbol">{symbol}</span>
      </span>
      <button onClick={clickHandler}>{isEditing ? "Save" : "Edit"}</button>
    </li>
  );
}

I was going through another lecture where we wanted to implement two way binding by displaying the inputted name on the screen once the submit button was clicked. My solution was

export default function Player() {
  let editingPlayerName = "";
  const [playerName, setPlayerName] = useState("");

  function handleChange(event) {
    editingPlayerName = event.target.value;
  }

  function handleClick() {
    setPlayerName(editingPlayerName);
  }

  return (
    <section id="player">
      <h2>Welcome {playerName ? playerName : "unknown entity"}</h2>
      <p>
        <input type="text" required onChange={handleChange} />
        <button onClick={handleClick}>Set Name</button>
      </p>
    </section>
  );
}

as you can see in my solution I dont have a value prop in my input component that I feed the state value back into. Instead, I use the state value within the h2 component. Would this still be considered two way binding in React? Also what is the point of the value prop in <input> since even without it I can see my user input when I type in the box


Solution

  • The concept of two-way binding in React typically refers to the synchronization of data between the state and the UI. In your first example, you're using controlled components, which is the recommended way of achieving two-way binding in React.

    In your second example, you're not using controlled components. Instead, you're directly updating the DOM with the user input without storing it in the component's state. While it works for displaying the inputted name, it doesn't follow the common React pattern of two-way binding.

    The value prop in the <input> element is part of what makes it a controlled component. When you use value and onChange together, you are telling React that the component's value is controlled by React state. The state (playerName in your case) is the single source of truth for the input value. Any changes to the input are reflected in the state, and any changes to the state are reflected in the input. This ensures that the component always displays the correct and up-to-date value.

    In your second example, without using the value prop, the input is uncontrolled. While it may work for simple cases, it can lead to unexpected behavior in more complex scenarios. Uncontrolled components are generally not recommended in React unless you have a specific reason for using them.

    So, to answer your question, your second example doesn't quite fit the typical definition of two-way binding in React. It's more of a one-way binding where you read the input value from the DOM when needed. Controlled components, as shown in your first example, are the recommended approach for achieving two-way binding in React.