Skip to content

React Tutorial Props and Data

Props Are Read-Only: Why You Must Not Mutate Props

Lesson 37 of 156 2 min read By Deepak Paswan Updated Oct 10, 2026

Runnable lesson · press Try it on the examples to edit and run them here.

React components should behave like pure functions with respect to their props: given the same props, return the same JSX, and never change the props themselves. The rule is: props are read-only.

What not to do

App.jsx
JSX
function Order({ items }) {
  items.push("free gift"); // mutates the array that the parent owns
  return <p>{items.length} items</p>;
}

function App() {
  const items = ["book", "pen"];
  return (
    <div>
      <Order items={items} />
      <Order items={items} />
    </div>
  );
}

Each render pushes another item into the same array that App created. The first Order shows 3 and the second 4, and the numbers grow every time React renders. The child silently changed data it does not own.

What to do instead

Create a new value from the prop and leave the original alone:

App.jsx
JSX
function Order({ items }) {
  const withGift = [...items, "free gift"]; // a new array
  return <p>{withGift.length} items</p>;
}

function App() {
  const items = ["book", "pen"];
  return (
    <div>
      <Order items={items} />
      <Order items={items} />
    </div>
  );
}

Both components show 3 items, always. Spread (...), map, filter, slice and Object.assign({}, obj) all make new values. See Avoiding State Mutation for the full toolbox.

Why is it a rule?

  • Predictability. A component whose output depends only on its props is easy to reason about and to test.
  • Rendering can happen any time. React may call your component more than once (Strict Mode does it on purpose in development). Mutations during render then repeat.
  • Optimisation depends on it. React and tools such as memo assume that “same props object means same output”.

What if I need to change it?

If a child needs to change data, the owner must do it. Pass a function down and call it (see Passing Functions as Props), or keep a local copy in state when the child really needs its own editable version.

App.jsx
JSX
function Editor({ initialText }) {
  // The child needs its own editable copy: local state, starting from the prop.
  const [text, setText] = React.useState(initialText);
  return (
    <div>
      <input aria-label="Draft" value={text} onChange={(e) => setText(e.target.value)} />
      <p>Draft: {text}</p>
    </div>
  );
}

function App() {
  return <Editor initialText="Hello" />;
}

Naming the prop initialText tells readers that later changes to it are ignored; it is only the starting value.

Key points

  • Never change a prop or anything inside it (push, assign, delete).
  • Create a changed copy instead.
  • If a child needs to change the data, call a function from the parent or keep local state.