15

The React documentation says: React is pretty flexible but it has a single strict rule: all React components must act like pure functions with respect to their props.

Why is that?

I guess that if you change directly the value of the props, the component does not re-render, that's why we must use setState. But I still don't understand the reason behind this. Why components must be like pure functions with respect to their props?

L. Pier Roberto
  • 513
  • 1
  • 6
  • 20
  • 1
    I think because they wanted the unidirectional flow to avoid ambiguity – Revansiddh Jul 20 '18 at 05:16
  • 2
    Possible duplicate of [Why can't I update props in react.js?](https://stackoverflow.com/questions/26089532/why-cant-i-update-props-in-react-js) Another Possible duplicate : https://stackoverflow.com/questions/47471131/why-are-react-props-immutable?rq=1 – Revansiddh Jul 20 '18 at 05:27
  • Possible duplicate of [Why are React props immutable](https://stackoverflow.com/questions/47471131/why-are-react-props-immutable/47471276#47471276) – Shubham Khatri Jul 20 '18 at 05:44
  • Props are something that we pass from one component to another and it is possible that `props` is being passed to multiple component. If we are allowing a component to update the props directly then it will render all the child component where the props is passed, which might not be expected but may work in few scenarios based on project. – Milind Agrawal Feb 10 '20 at 13:38

2 Answers2

8

The important concept of React component: a component should only manage its own state, but it should not manage its own props.

In fact, props of a component is concretely "the state of the another component (parent component)". So props must be managed by their component owner. That's why all React components must act like pure functions with respect to their props (not to mutate directly their props).

I will show you a simple example:

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      p1: {a:1, b:2},
    }

   render() {
      return <ChildComponent p1={this.state.p1} />     
   }
}

In the ChildComponent, if you want to mutate the "passed prop p1" (p1 is an object with his own ref) (ex. in the ChildComponent, you write: p1.a=3), so evidently, "the p1 - property of the state of ParentComponent" is also mutated. But the ParentComponent couldn't re-render in this case because you didn't trigger the action setState() in ParentComponent. So it will generate many uncontrolled bugs for a React App unstable.

I hope right now that you can understand why React says:

The strict rule: all React components must act like pure functions with respect to their props (not to mutate directly their props).


Bonus: for correctly changing (mutating) the props, you must use "callback fnc prop" in ChildComponent. Right now, it respects well the concept of React Component.

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      p1: {a:1, b:2},
  }

  this.changeP1 = () => {
     this.setState({p1: {a:3, b:4}});
  }

   render() {
      return <ChildComponent p1={this.state.p1} changeP1={this.changeP1} />     
   }
}
SanjiMika
  • 2,664
  • 19
  • 19
0

docs

React docs said

All React components must act like pure functions with respect to their props. Of course, application UIs are dynamic and change over time. In the next section, we will introduce a new concept of “state”. State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule.

MJ Studio
  • 3,947
  • 1
  • 26
  • 37