-1

I'm just learning React and I've come across something I can't find explained anywhere.

In every book/blog that I've read about React components I've seen a statement along the lines that component props are immutable. The only way to change a component's properties is to re-create it. That appears to not be the case, though.

In reading "React in Action" and "React Quickly" I've run across references to componentWillReceiveProps along with an explanation that this method is to be used when props (not state) is to be changed. I've seen the documentation for this (and the newer getDerivedStateFromProps function).

The documentation for componentWillReceiveProps stated:

componentWillReceiveProps() is invoked before a mounted component receives new props. 

The documentation for getDerivedStateFromProps states:

This method exists for rare use cases where the state depends on changes in props over time. 

Neither of these explains how it is that immutable props can be received (and changed?) at any time during the life of a component.

So, what is really going on here? If props can't be changed what are these functions/methods for? Or, are the books/blogs mistaken and these really are not immutable after all?

kind user
  • 40,029
  • 7
  • 67
  • 77
melston
  • 2,198
  • 22
  • 39
  • To those who down-voted the question, please understand that the descriptions you find almost everywhere describe React components as having immutable props. This is very confusing and misleading. Props can't be changed from within the component but apparently they can be changed by the parent. It is a quirk of the lifecycle that is not really explained anywhere that I saw until @ray_hatfield pointed it out. – melston Oct 07 '20 at 22:25

1 Answers1

2

A component can be re-rendered with new/updated/different props. Consider the following component:

function Parent () {
    const [count, setCount] = useState(0);

    setInterval(() => setCount(count + 1), 1000);

    return (
      <CounterDisplay count={count} />
    )
}

The CounterDisplay component will get re-rendered with a new count prop once every second(ish). CounterDisplay could implement componentWillReceiveProps if it needed to do something in response to the new prop before re-rendering.

In practice this is pretty rare in projects running recent versions of React. I haven't implemented a componentWillReceiveProps method in a React component in years.

ray
  • 26,557
  • 5
  • 28
  • 27
  • I wasn't aware that this would 're-use' an existing component. I thought it would re-render with a new `CounterDisplay` component entirely. How does this square with props being passed in to the constructor, though. Doesn't that imply a new component being constructed? Or does React silently update the props and call `render` on the child component (after calling `getDerivedStateFromProps` now)? – melston Sep 29 '20 at 00:54
  • The constructor is called when the component is initially instantiated. React will reuse/re-render the existing instance when props or state change as long as it remains mounted. – ray Sep 29 '20 at 00:58
  • Thanks. That explains it. My understanding of the lifecycle was off. It makes sense that a framework that is all about efficiency wouldn't unmount a component because it was being re-rendered with new props. I just hadn't thought of it that way. – melston Sep 29 '20 at 01:01
  • For what it's worth: I can't remember the last time I wrote a class component. It's all function components and hooks now. – ray Sep 29 '20 at 01:17