Bisakah saya memperbarui properti komponen di React.js?

217

Setelah mulai bekerja dengan React.js, sepertinya propsdimaksudkan untuk menjadi statis (diteruskan dari komponen induk), sementara stateperubahan didasarkan pada peristiwa. Namun, saya perhatikan dalam dokumen itu referensi componentWillReceiveProps, yang secara khusus mencakup contoh ini:

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

Ini tampaknya menyiratkan bahwa properti BISA berubah pada komponen berdasarkan perbandingan nextPropske this.props. Apa yang saya lewatkan? Bagaimana alat peraga berubah, atau apakah saya salah tentang di mana ini dipanggil?

Matt Huggins
sumber

Jawaban:

250

Sebuah komponen tidak dapat memperbarui propsnya sendiri kecuali jika mereka adalah array atau objek (memiliki komponen memperbarui propsnya sendiri walaupun mungkin merupakan anti-pola), tetapi dapat memperbarui status dan props dari anak-anaknya.

Misalnya, Dasbor memiliki speedbidang dalam kondisinya, dan meneruskannya ke anak Gauge yang menampilkan kecepatan ini. Its rendermetode hanya return <Gauge speed={this.state.speed} />. Saat Dashboard memanggil this.setState({speed: this.state.speed + 1}), Gauge ditampilkan ulang dengan nilai baru untuk speed.

Tepat sebelum ini terjadi, Gauge componentWillReceivePropsdisebut, sehingga Gauge memiliki kesempatan untuk membandingkan nilai baru dengan yang lama.

Valéry
sumber
Jadi kedengarannya seperti itu dipanggil sekali ketika komponen Bereaksi diinisialisasi dan menerima alat peraga. Alat peraga tidak benar-benar "berubah" setelah komponen dibuat. Apakah itu benar?
Matt Huggins
12
Sebaliknya. The dokumentasi mengatakan: "dipanggil ketika komponen menerima alat peraga baru Metode ini tidak disebut untuk awal render.."
Valéry
Terima kasih. Pertanyaan ini datang dari kesalahpahaman awal Bereaksi bahwa suatu komponen akan digunakan kembali ketika rerendering layar (atau bagian dari layar).
Matt Huggins
1
Iya. Sebuah komponen dapat mendengarkan suatu acara, dan memperbarui kondisinya setiap kali acara tersebut menyala.
Valéry
8
Saya datang dari masa depan: componentWillReceivePropssudah ketinggalan zaman sekarang: dan digantikan oleh kombinasi dari getDerivedStateFromPropsdan componentDidUpdate.
bvdb
53

ATRIBUT

Komponen Bereaksi harus menggunakan alat peraga untuk menyimpan informasi yang dapat diubah, tetapi hanya dapat diubah oleh komponen yang berbeda.

NEGARA

Komponen Bereaksi harus menggunakan status untuk menyimpan informasi yang dapat diubah oleh komponen itu sendiri.

Contoh yang baik sudah disediakan oleh Valéry.

Ali Adravi
sumber
4
@ali_adravi adalah kutipan yang disalin dari suatu tempat? Jika demikian, apa rujukannya? Atau apakah itu kata-kata Anda, dan Anda hanya memformatnya sebagai kutipan untuk penekanan?
Rob Bednark
@RobBednark Saya tidak ingat sumber pastinya sekarang, tetapi yakin itu adalah pernyataan yang benar dengan sedikit modifikasi dalam kalimat dari beberapa buku.
Ali Adravi
26

Alat peraga dapat berubah ketika induk komponen membuat komponen lagi dengan properti yang berbeda. Saya pikir ini sebagian besar merupakan optimasi sehingga tidak ada komponen baru yang perlu dipakai.

Joost Diepenmaat
sumber
3

Trik untuk memperbarui alat peraga jika 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,
  },
});
Abhishek Kumar
sumber
3
Saya berpikir bahwa menginisialisasi keadaan dengan alat peraga adalah anti-pola, harus dihindari. di sini adalah tautan yang bagus untuk dibaca github.com/vasanthk/react-bits/blob/master/anti-patterns/… .
tryHendri
0

jika Anda menggunakan recompose, gunakan mapPropsuntuk membuat alat peraga baru yang berasal dari alat peraga yang masuk

Edit misalnya:

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);
ehacinom
sumber
tolong berikan contoh
vsync