Posso atualizar os adereços de um componente no React.js?


217

Depois de começar a trabalhar com o React.js, parece que ele propsdeve ser estático (transmitido do componente pai), enquanto as statealterações são baseadas em eventos. No entanto, notei nos documentos uma referência a componentWillReceiveProps, que inclui especificamente este exemplo:

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

Isso parece implicar que as propriedades PODEM mudar em um componente com base na comparação de nextPropspara this.props. o que estou perdendo? Como os adereços mudam ou estou enganado sobre como isso é chamado?

Respostas:


249

Um componente não pode atualizar seus próprios adereços, a menos que sejam matrizes ou objetos (ter um componente atualizando seus próprios adereços, mesmo que possível seja um antipadrão), mas pode atualizar seu estado e os adereços de seus filhos.

Por exemplo, um painel tem um speedcampo em seu estado e o passa para um filho do Gauge que exibe essa velocidade. Seu rendermétodo é justo return <Gauge speed={this.state.speed} />. Quando o Painel chama this.setState({speed: this.state.speed + 1}), o Medidor é renderizado novamente com o novo valor para speed.

Antes que isso aconteça, o Gauge componentWillReceivePropsé chamado, para que o Gauge tenha a chance de comparar o novo valor ao antigo.


Parece que é chamado uma vez quando o componente React é inicializado e está recebendo adereços. Na verdade, os objetos não "mudam" quando um componente é criado. Isso está certo?
precisa

12
O oposto. A documentação diz: "Chamado quando um componente está recebendo novos adereços. Este método não é chamado para a renderização inicial".
Valéry

Obrigado. Essa pergunta veio de um mal-entendido inicial do React, em que um componente será reutilizado ao renderizar novamente a tela (ou parte da tela).
precisa

1
Sim. Um componente pode ouvir um evento e atualizar seu estado sempre que o evento for disparado.
Valéry

8
Eu venho do futuro: componentWillReceivePropsestá desatualizado agora: e substituído por uma combinação de getDerivedStateFromPropse componentDidUpdate.
bvdb

53

ADEREÇOS

Um componente React deve usar adereços para armazenar informações que podem ser alteradas, mas só podem ser alteradas por um componente diferente.

ESTADO

Um componente React deve usar state para armazenar informações que o próprio componente pode alterar.

Um bom exemplo já é fornecido pela Valéry.


4
@ali_adravi são aquelas citações copiadas de algum lugar? Em caso afirmativo, qual é a referência? Ou são essas as suas palavras e você as formatou como aspas para enfatizar?
precisa saber é o seguinte

@ RobBednark Não me lembro da fonte exata agora, mas com certeza essa é a afirmação verdadeira com uma pequena modificação na frase de algum livro.
Ali Adravi 26/09/18

26

Os adereços podem mudar quando o pai de um componente o renderiza novamente com propriedades diferentes. Eu acho que isso é principalmente uma otimização para que nenhum novo componente precise ser instanciado.


3

Truque para atualizar adereços se eles são 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,
  },
});

3
Eu estou pensando que inicializar estado com adereços é anti-padrão, deve ser evitado. aqui está o bom link para ler github.com/vasanthk/react-bits/blob/master/anti-patterns/… .
tryHendri


0

se você usar recompose, usemapProps para criar novos adereços derivados dos adereços recebidos

Edite por exemplo:

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

forneça um exemplo
vsync
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.