Can I update a component's props in React.js?

JavascriptReactjsProperties

Javascript Problem Overview


After starting to work with React.js, it seems like props are intended to be static (passed in from the parent component), while state changes based upon events. However, I noticed in the docs a reference to componentWillReceiveProps, which specifically includes this example:

componentWillReceiveProps: function(nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

This seems to imply that the properties CAN change on a component based upon the comparison of nextProps to this.props. What am I missing? How do props change, or am I mistaken about where this gets called?

Javascript Solutions


Solution 1 - Javascript

A component cannot update its own props unless they are arrays or objects (having a component update its own props even if possible is an anti-pattern), but can update its state and the props of its children.

For instance, a Dashboard has a speed field in its state, and passes it to a Gauge child thats displays this speed. Its render method is just return <Gauge speed={this.state.speed} />. When the Dashboard calls this.setState({speed: this.state.speed + 1}), the Gauge is re-rendered with the new value for speed.

Just before this happens, Gauge's componentWillReceiveProps is called, so that the Gauge has a chance to compare the new value to the old one.

Solution 2 - Javascript

PROPS

> A React component should use props to store information that can be > changed, but can only be changed by a different component.

STATE

> A React component should use state to store information that the > component itself can change.

A good example is already provided by Valéry.

Solution 3 - Javascript

Props can change when a component's parent renders the component again with different properties. I think this is mostly an optimization so that no new component needs to be instantiated.

Solution 4 - Javascript

Much has changed with hooks, e.g. componentWillReceiveProps turned into useEffect+useRef (as shown in this other SO answer), but Props are still Read-Only, so only the caller method should update it.

Solution 5 - Javascript

Trick to update props if they are array :

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button
} from 'react-native';

class Counter extends Component {
  constructor(props) {
    super(props);
      this.state = {
        count: this.props.count
      }
    }
  increment(){
    console.log("this.props.count");
    console.log(this.props.count);
    let count = this.state.count
    count.push("new element");
    this.setState({ count: count})
  }
  render() {

    return (
      <View style={styles.container}>
        <Text>{ this.state.count.length }</Text>
        <Button
          onPress={this.increment.bind(this)}
          title={ "Increase" }
        />
      </View>
    );
  }
}

Counter.defaultProps = {
 count: []
}

export default Counter
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

Solution 6 - Javascript

If you use recompose, use mapProps to make new props derived from incoming props

Example:

import { compose, mapProps } from 'recompose';

const SomeComponent = ({ url, onComplete }) => (
  {url ? (
    <View />
  ) : null}
)

export default compose(
  mapProps(({ url, storeUrl, history, ...props }) => ({
    ...props,
    onClose: () => {
      history.goBack();
    },
    url: url || storeUrl,
  })),
)(SomeComponent);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatt HugginsView Question on Stackoverflow
Solution 1 - JavascriptValéryView Answer on Stackoverflow
Solution 2 - JavascriptAli AdraviView Answer on Stackoverflow
Solution 3 - JavascriptJoost DiepenmaatView Answer on Stackoverflow
Solution 4 - Javascripttales.aparecidaView Answer on Stackoverflow
Solution 5 - JavascriptAbhishek KumarView Answer on Stackoverflow
Solution 6 - JavascriptehacinomView Answer on Stackoverflow