簡體   English   中英

我可以在 React.js 中更新組件的 props 嗎?

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

在開始使用 React.js 之后, props似乎是靜態的(從父組件傳入),而state基於事件而變化。 但是,我在文檔中注意到對componentWillReceiveProps的引用,其中特別包含以下示例:

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

這似乎意味着屬性可以根據nextPropsthis.props的比較在nextPropsthis.props 我錯過了什么? props 是如何變化的,或者我是否誤解了它在哪里被調用?

一個組件不能更新它自己的 props,除非它們是數組或對象(即使可能,讓組件更新它自己的 props 是一種反模式),但可以更新它的 state 和它的孩子的 props。

例如,儀表板在其狀態中有一個speed字段,並將其傳遞給顯示此速度的儀表子項。 它的render方法只是return <Gauge speed={this.state.speed} /> 當 Dashboard 調用this.setState({speed: this.state.speed + 1}) ,儀表會使用新的speed值重新渲染。

就在這發生之前,Gauge 的componentWillReceiveProps被調用,以便 Gauge 有機會將新值與舊值進行比較。

道具

React 組件應該使用 props 來存儲可以更改的信息,但只能由不同的組件更改。

狀態

React 組件應該使用狀態來存儲組件本身可以更改的信息。

Valéry 已經提供了一個很好的例子。

當組件的父級再次使用不同的屬性渲染組件時,道具可能會發生變化。 我認為這主要是一種優化,因此不需要實例化新組件。

鈎子發生了很多變化,例如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
      }
    }
  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,
  },
});

如果您使用recompose ,請使用mapProps從傳入的 props 派生出新的 props

編輯例如:

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM