React.js'deki bir bileşenin özelliklerini güncelleyebilir miyim?


217

React.js ile çalışmaya başladıktan sonra props, stateolaylara bağlı olarak değişiklikler yapılırken statik (ana bileşenden aktarılır) olması amaçlanmıştır . Ancak, dokümanlar componentWillReceivePropsiçinde özellikle bu örneği içeren bir referans fark ettim :

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

Bu özellikler kıyaslanmasına dayalı bir bileşende değiştirmek CAN ima görünüyor nextPropsiçin this.props. Neyi kaçırıyorum? Destekler nasıl değişir veya bunun nereden çağrıldığı konusunda yanılıyor muyum?

Yanıtlar:


249

Bir bileşen, diziler veya nesneler olmadıkça kendi bileşenlerini güncelleyemez (bir bileşenin mümkünse bile kendi desteklerini güncelleştirmesi bir anti-desen olsa da), ancak durumunu ve çocuklarının sahne özelliklerini güncelleyebilir.

Örneğin, bir Gösterge Tablosunun speeddurumunda bir alan vardır ve bunu bu hızı görüntüleyen bir Ölçer alt öğesine geçirir. Onun renderyöntemi sadece return <Gauge speed={this.state.speed} />. Gösterge Tablosu aradığında this.setState({speed: this.state.speed + 1}), Gösterge için yeni değerle yeniden oluşturulur speed.

Bu gerçekleşmeden hemen önce Gauge's componentWillReceivePropsçağrılır, böylece Gauge yeni değeri eskisiyle karşılaştırır.


Yani React bileşeni başlatıldığında ve sahne alırken bir kez çağrılmış gibi geliyor. Bir bileşen oluşturulduktan sonra sahne donanımı aslında "değişmez". Bu doğru mu?
Matt Huggins

12
Tam tersi. Dokümantasyon diyor ki: "çağrılan bir bileşeni yeni sahne alırken ilk kılmak için bu yöntem çağrılmaz.".
Valéry

Teşekkürler. Bu soru, Ekranı (veya ekranın bir bölümünü) yeniden gönderirken bir bileşenin yeniden kullanılacağı için React'ın ilk yanlış anlaşılmasından kaynaklandı.
Matt Huggins

1
Evet. Bir bileşen bir olayı dinleyebilir ve olay her tetiklendiğinde durumunu güncelleyebilir.
Valéry

8
Ben gelecekten gelip: componentWillReceivePropsşimdi modası geçmiş: bir kombinasyonu ile değiştirilir getDerivedStateFromPropsve componentDidUpdate.
bvdb

53

PROPS

Bir React bileşeni, değiştirilebilen ancak yalnızca farklı bir bileşen tarafından değiştirilebilen bilgileri saklamak için sahne donanımı kullanmalıdır.

DURUM

React bileşeni, bileşenin kendisinin değiştirebileceği bilgileri depolamak için durumu kullanmalıdır.

Valéry tarafından zaten iyi bir örnek verilmiştir.


4
@ali_adravi Bu alıntılar bir yerden mi kopyalanıyor? Eğer öyleyse, referans nedir? Yoksa sözlerin bunlar mı ve onları sadece vurgu için alıntı olarak mı biçimlendirdin?
Rob Bednark

@RobBednark Şu anki kaynağı tam olarak hatırlamıyorum, ancak bunun bir kitaptan cümle içinde küçük bir değişiklikle doğru ifade olduğundan eminim.
Ali Adravi

26

Bir bileşenin üst bileşeni, bileşeni farklı özelliklerle yeniden oluşturduğunda aksesuarlar değişebilir. Bence bu çoğunlukla bir optimizasyon ve böylelikle yeni bir bileşenin somutlaştırılması gerekmiyor.


3

Dizi ise sahne güncellemenin hilesi:

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

3
Ben sahne ile sahne başlatmak anti-desen olduğunu düşünüyorum, kaçınılmalıdır. github.com/vasanthk/react-bits/blob/master/anti-patterns/… adresini okumak için iyi bir bağlantı .
tryHendri


0

kullanıyorsanız recompose, mapPropsgelen sahne aksesuarlarından türetilen yeni sahne yapmak için kullanın

Örneğin düzenleyin:

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

lütfen bir örnek verin
vsync
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.