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?
This question is related to
javascript
reactjs
properties
higher-order-components
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.
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.
if you use recompose
, use mapProps
to make new props derived from incoming props
Edit for 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);
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.
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,
},
});
Source: Stackoverflow.com