Isso pode estar trilhando essa linha entre respondente e opinativo, mas eu estou indo e voltando sobre como estruturar um componente ReactJS à medida que a complexidade cresce e pode usar alguma direção.
Vindo do AngularJS, quero passar meu modelo para o componente como uma propriedade e fazer com que o componente modifique o modelo diretamente. Ou devo dividir o modelo em várias state
propriedades e compilá-lo novamente ao enviá-lo de volta? Qual é a maneira ReactJS?
Veja o exemplo de um editor de postagem no blog. Tentar modificar o modelo diretamente acaba parecendo:
var PostEditor = React.createClass({
updateText: function(e) {
var text = e.target.value;
this.props.post.text = text;
this.forceUpdate();
},
render: function() {
return (
<input value={this.props.post.text} onChange={this.updateText}/>
<button onClick={this.props.post.save}/>Save</button>
);
}
});
O que parece errado.
É mais a maneira React de criar nossa text
propriedade de modelo state
e compilá-la novamente no modelo antes de salvar como:
var PostEditor = React.createClass({
getInitialState: function() {
return {
text: ""
};
},
componentWillMount: function() {
this.setState({
text: this.props.post.text
});
},
updateText: function(e) {
this.setState({
text: e.target.value
});
},
savePost: function() {
this.props.post.text = this.state.text;
this.props.post.save();
},
render: function() {
return (
<input value={this.state.text} onChange={this.updateText}/>
<button onClick={this.savePost}/>Save</button>
);
}
});
Isso não requer uma chamada this.forceUpdate()
, mas à medida que o modelo cresce, (uma postagem pode ter um autor, assunto, tags, comentários, classificações, etc ...) o componente começa a ficar realmente complicado.
O primeiro método com o ReactLink é o caminho a seguir?
text
campo, tenhamos umsetText
método que faça validação e outras coisas. Eu posso ver o método (2) funcionando sesetText
for puro e retornar uma nova instância do modelo. No entanto, sesetText
apenas atualizar o estado interno, ainda precisaríamos chamarforceUpdate
, certo?forceUpdate
, mas nesse ponto você está "vazando" do React. Talvez seja melhor passar umsetState()
retorno de chamada para o modelo opaco para evitar ter que disparar manualmente as renderizações novamente.Atualização de 2016: a reação foi alterada e a explicação "props vs state" se tornou muito simples. Se um componente precisar alterar dados - coloque-o em um estado, caso contrário, em adereços. Porque adereços são somente leitura agora.
Qual é a diferença exata entre adereços e estado?
Você pode encontrar uma boa explicação aqui (versão completa)
fonte
setProps
está obsoleto e não deve ser usado. Substituição é renderizar novamente o componente e deixar o React lidar com as diferenças.Do documento React
No TrySpace : quando props (ou state) são atualizados (via setProps / setState ou parent), o componente é renderizado novamente.
fonte
Uma leitura de Thinking in React :
fonte
Não tenho certeza se estou respondendo à sua pergunta, mas descobri que, especialmente em um aplicativo grande / crescente, o padrão Container / Component funciona incrivelmente bem.
Essencialmente, você tem dois componentes do React:
Exemplo
NB Este exemplo é provavelmente muito simples para ilustrar os benefícios desse padrão, pois é bastante detalhado para um caso tão simples.
Benefícios
Ao manter a lógica de exibição e o gerenciamento de dados / estado separados, você tem um componente de exibição reutilizável que:
Você também tem um componente de contêiner que lida com toda a comunicação externa. Isso deve facilitar a flexibilidade da maneira como você acessa seus dados, se você fizer alterações sérias mais tarde *.
Esse padrão também torna a escrita e a implementação de testes de unidade muito mais diretas.
Depois de iterar um grande aplicativo React algumas vezes, descobri que esse padrão mantém as coisas relativamente indolor, especialmente quando você tem componentes maiores com estilos calculados ou interações DOM complicadas.
* Leia o padrão de fluxo e dê uma olhada no
Marty.js , que inspirou amplamente essa resposta (e eu tenho usado muito ultimamente)Redux (e react-redux ), que implementa esse padrão extremamente bem.fonte
Eu acho que você está usando um anti-padrão que o Facebook já explicou neste link
Aqui está o que você está encontrando:
A primeira vez que o componente interno for renderizado, ele terá {foo: 'bar'} como o valor prop. Se o usuário clicar na âncora, o estado do componente pai será atualizado para {value: {foo: 'barbar'}}, acionando o processo de re-renderização do componente interno, que receberá {foo: 'barbar'} como o novo valor para o suporte.
O problema é que, como os componentes pai e interno compartilham uma referência ao mesmo objeto, quando o objeto é alterado na linha 2 da função onClick, o suporte do componente interno será alterado. Portanto, quando o processo de nova renderização for iniciado e o invocadorComponentUpdate for invocado, this.props.value.foo será igual a nextProps.value.foo, porque, na verdade, this.props.value faz referência ao mesmo objeto que nextProps.value.
Consequentemente, como perderemos a alteração no suporte e curto-circuito no processo de nova renderização, a interface do usuário não será atualizada de 'bar' para 'barbar'
fonte
Innercomponents
código?