Hiprup

What is unidirectional data flow in React?

Unidirectional data flow means data in React moves one way only — from parent components down to children via props. Children cannot directly modify their parent's data; they communicate back by calling callbacks the parent passed in.

  • Predictable — you can trace where any piece of data came from by following the tree upward.

  • Easier debugging — only one place can change a piece of state; bugs are easier to localize.

  • Source of truth — state lives at one level; lower components are pure functions of props.

  • Callbacks bubble up — child events trigger parent-supplied functions; the parent decides what to update.

  • Lift state up — if siblings need shared data, hoist it to the closest common ancestor.

  • Contrast with two-way binding — AngularJS-style two-way binding lets children mutate parent data directly; harder to reason about at scale.

function Parent() {
  const [items, setItems] = useState(['Apple', 'Banana']);

  const addItem = (item) => {
    setItems([...items, item]);
  };

  return (
    <div>
      <ItemList items={items} />       {/* Data flows down */}
      <AddItemForm onAdd={addItem} />  {/* Callback flows down */}
    </div>
  );
}

function ItemList({ items }) {
  return (
    <ul>
      {items.map((item, i) => <li key={i}>{item}</li>)}
    </ul>
  );
}

function AddItemForm({ onAdd }) {
  const [value, setValue] = useState('');
  return (
    <form onSubmit={(e) => { e.preventDefault(); onAdd(value); setValue(''); }}>
      <input value={value} onChange={(e) => setValue(e.target.value)} />
      <button type="submit">Add</button>
    </form>
  );
}

Parent owns the items state and passes it down to ItemList (data flows down as props). AddItemForm receives a callback (onAdd) and calls it when the user submits.

The parent updates its state, which triggers a re-render, and the new items flow down again. Data always moves in one direction: parent -> child.

Explain the flow: state -> props -> render -> callback -> state update -> re-render. Compare with two-way binding to show you understand the trade-off: predictability vs convenience.

What is unidirectional data flow in React? | Hiprup