Могу ли я обновить реквизиты компонента в React.js?
После начала работы с React.js, похоже, props
должны быть статическими (передаваться из родительского компонента), а state
изменения на основе событий. Тем не менее, я заметил в документах ссылку на componentWillReceiveProps
, который конкретно включает в себя этот пример:
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
Это, кажется, подразумевает, что свойства МОГУТ изменяться на компоненте на основе сравнения nextProps
в this.props
, Что мне не хватает? Как меняется реквизит, или я ошибаюсь, откуда это вызывается?
5 ответов
Компонент не может обновлять свои собственные реквизиты, если они не являются массивами или объектами (если компонент обновляет свои собственные реквизиты, даже если это возможно, является антишаблоном), но он может обновлять свое состояние и реквизиты своих дочерних элементов.
Например, панель инструментов имеет speed
поле в его состоянии, и передает его дочернему элементу датчика, который отображает эту скорость. это render
метод просто return <Gauge speed={this.state.speed} />
, Когда приборная панель вызывает this.setState({speed: this.state.speed + 1})
, Датчик повторно отображается с новым значением для speed
,
Как раз перед тем, как это произойдет, Gauge's componentWillReceiveProps
называется, так что датчик имеет возможность сравнить новое значение со старым.
РЕКВИЗИТ
Компонент React должен использовать реквизиты для хранения информации, которая может быть изменена, но может быть изменена только другим компонентом.
ГОСУДАРСТВО
Компонент React должен использовать состояние для хранения информации, которую сам компонент может изменить.
Хороший пример уже предоставлен Валери.
Реквизит может измениться, когда родительский компонент компонента снова отображает его с другими свойствами. Я думаю, что это в основном оптимизация, поэтому нет необходимости создавать новые компоненты.
Многое изменилось с крючками, например componentWillReceiveProps
превратился в useEffect
+useRef
( как показано в этом другом ответе SO), но Props по-прежнему доступны только для чтения, поэтому только метод вызывающего должен обновлять его.
Хитрость для обновления реквизита, если он является массивом:
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,
},
});
Если вы используете 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);