在开始使用React.js后,似乎props
是静态的(从父组件传入),而state
基于事件而变化。但是,我在文档中注意到componentWillReceiveProps
的引用,其具体包括此示例:
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
这似乎意味着基于nextProps
与this.props
的比较,属性可以在组件上发生变化。我错过了什么?道具是如何改变的,还是我错误地将其称为什么?
答案 0 :(得分:196)
组件无法更新自己的道具,除非它们是数组或对象(即使可能是反模式,组件更新自己的道具),但可以更新其状态及其子项的道具。
例如,仪表板的状态为speed
字段,并将其传递给显示此速度的Gauge子项。它的render
方法只是return <Gauge speed={this.state.speed} />
。当仪表板调用this.setState({speed: this.state.speed + 1})
时,将使用speed
的新值重新呈现Gauge。
在此之前,会调用Gauge的componentWillReceiveProps
,以便Gauge有机会将新值与旧值进行比较。
答案 1 :(得分:21)
当组件的父级使用不同的属性再次呈现组件时,道具可以更改。我认为这主要是一种优化,因此不需要实例化新的组件。
答案 2 :(得分:18)
道具
React组件应使用道具来存储可以 已更改,但只能由其他组件更改。
状态
React组件应使用状态来存储以下信息: 组件本身可以更改。
Valéry已经提供了一个很好的例子。
答案 3 :(得分:2)
如果它们是数组,则欺骗更新道具:
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
}
}
increament(){
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.increament.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,
},
});
答案 4 :(得分:0)
如果您使用recompose
,请使用mapProps
制作从传入道具衍生而来的新道具
例如编辑:
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);
答案 5 :(得分:0)
钩子已经发生了很多变化,例如componentWillReceiveProps
变成了useEffect
+ useRef
(as shown in this other SO answer),但是变成了Props are still Read-Only,因此只有调用者方法才应该对其进行更新。