Componentes inteligentes versus burros: quando usar quais

AVISO LEGAL

Este é um artigo antigo escrito originalmente como um artigo para o site de documentos não publicados para uma estrutura que costumava desenvolver chamada “NUI”. Isso está sendo postado literalmente e pode conter referências a Nui. Se você não está familiarizado com ele, o Nui era uma estrutura de desenvolvimento rápido React de nível empresarial. A maior parte (não todo) do meu foco no projeto, desde então, mudou para alguns outros módulos de nó que desenvolvo e mantenho.

Dito isso, novamente, este artigo nunca foi publicado ou extensivamente revisado por pares. Pode haver alguma informação ausente ou desatualizada. Se você encontrar algum, sinta-se à vontade para avisar nos comentários!

Componentes inteligentes vs burros

Sejam componentes React para aplicativos Redux ou Nui

Resolva a questão de “quando” – qual é a diferença?

Os componentes fornecem uma quantidade imensa de recursos aos desenvolvedores. A capacidade de criar marcação diretamente acoplada ao seu controlador reinventou o desenvolvimento de front-end como um todo. Existem muitos benefícios em usar componentes.

Pro ou Noob

Quer você seja um profissional ou um novato no React , às vezes nos deixamos levar. Tudo realmente tem que ser um componente com estado? Existe um incentivo para usar alguma outra alternativa? Quais são as implicações de desempenho?

Ambos os componentes Smart e Dumb são ferramentas importantes para escrever aplicativos da web bem escritos, de alto funcionamento e otimizados. Para responder às perguntas acima, falaremos sobre o propósito e a diferença entre os componentes inteligentes e os componentes burros e exploraremos exemplos de como usá-los adequadamente.

Componentes inteligentes e burros

Qual é a diferença?

A é qualquer componente que gerencia seu próprio estado. Ao trabalhar com o Babel ou o React no estilo ES6, passamos a conhecer isso como qualquer objeto semelhante a isso . Isso inclui um ou no nosso caso .Smart Componentclassextends ComponentReact.ComponentNui.Types.Component

export default Nui => class MyComponent extends Nui.Types.Component {
render
() {
return (
<h1>Hello World</h1>
);
}
}

(Veja aqui a referência Nui.Types.Component)

A pode ser facilmente definido como um componente sem estado. Um componente sem estado é muito mais eficiente do que um com estado, porque não requer tantos recursos do computador para renderizar (memória, CPU e GPU em termos de aplicativos com muitos gráficos).Dumb Component

export default Nui => () => (
<h1>Hello World</h1>
);

(Veja aqui como a exportação e as dependências funcionam no Nui)

Mas como e quando você os usa?

O conceito-chave: Contextual Irrelevance

Uma das perguntas mais difíceis de responder tem sido: “Quando você usa um contra o outro?” Tradicionalmente, a resposta raramente pode ser reduzida a um termo ou palavra que descreve uma melhor prática ou padrão que podemos usar para implementar em quase todos os cenários. Normalmente, a resposta é longa e prolongada, com vários “mas” misturados. Isso definitivamente torna difícil categorizar nossos componentes.

Contextual Irrelevanceé um teste exclusivo para determinar se seu componente deve ser inteligente ou mudo. Tudo se resume à funcionalidade e função que seu componente desempenha em seu aplicativo. Seu componente contém funcionalidade ou manipula dados que são ?Contextually Irrelevant

Em outras palavras, seu componente lida com informações ou funcionalidade que são irrelevantes para onde você usa seu componente?

Vamos explorar alguns exemplos:

  • Um TextInputcomponente: mudo
  • Um Dropdowncomponente: inteligente

Nosso componente estúpido poster-filho: TextInput

Como mencionamos anteriormente, os componentes mudos são muito mais eficientes. Eles requerem menos recursos e seu código-fonte é geralmente muito mais simples.

Um exemplo simples de um componente mudo é um TextInputcomponente personalizado . Na maioria dos casos, recebem seus valores de componentes pais, de modo que a necessidade de acompanhar o que exibir e quais valores são selecionados é aliviada por seu componente de controle.Form Element Components

Nosso TextInputcomponente será um componente Input emparelhado com um componente Label. Para isso, precisamos esperar alguns adereços:

  • value: O valor para o Input
  • labelText: O texto para o Label
  • onChange: Uma função que executaremos sempre que alguém digitar

Simples o suficiente, certo? Agora, vamos dar uma olhada em como nosso código pode ser (o de nossos componentes composition):

/* File: views/TextInput.jsx */
export default Nui => ({ value, labelText, onChange }) => (
<label>
<strong>{labelText}</strong>
<input type="text" onChange={onChange} value={value} />
</label>
);

Adicione um pouco de estilo e você terá um componente simples que o salvará de algumas repetições ao criar formulários para seu aplicativo.

Tudo é contextualmente relevante
Em nosso componente burro, tudo era contextualmente relevante . Este componente pode ser usado de várias maneiras Forms. Cada um de nós propsé específico sobre como e onde estamos investindo no momento. Ela terá um totalmente diferente , ou quando usado por um campo em um formulário de contato, em seguida, quando usado para um campo em um formulário de login. Todos os são ; ou seja, eles são relevantes para o contexto em que estão colocados. “Que forma está sendo usada neste momento?” determina o que damos.<TextInput />valueonChangelabelTextFirst NameUsernamepropsContextually Relevantprops

Um componente inteligente: Dropdown

Observe como, no exemplo acima, não tínhamos nenhum motivo para gerenciar o estado do componente porque todas as peças de que precisávamos foram fornecidas de forma conveniente pelo componente pai.

No entanto, só porque podemos obter propsde nosso componente pai, não significa que sempre devemos. Mesmo nos casos em que poderíamos obter o estado de um componente pai, provavelmente não deveríamos . É aqui que entra em jogo.Contextual Irrelevance

Vamos explorar um Dropdowncontrole para que possamos entender porque um Smart Component é mais adequado neste caso.

O que precisamos acompanhar, como no nosso Dropdown?

  • labelText: O texto para o Label
  • options: Um conjunto de opções que o usuário pode escolher.
  • selected: A opção atualmente selecionada.
  • onChange: Uma função que executaremos sempre que alguém escolher uma opção.
  • expanded: Um booleano que usaremos para controlar se a lista está ou não expandida ou reduzida.

Então, vamos ver como pode ser a composição do nosso componente inteligente:

/* File: views/Dropdown.jsx */
export default Nui => class DropdownComponent extends Nui.Component {
constructor(props) {
// Super must be called when extending another class
super
(props);

// Set our initial State
this.state = {
// Preserve any of the state the `super` may have added
...this.state,
// Start the component collapsed
expanded
: false
};

// Bind `toggleOptions` so we can use it in props
this.toggleOptions = this.toggleOptions.bind(this);
}

generateOption
(option) {
// Grab the `selected`, and `onChange` props
// These are props passed to us by the parent
const { selected, onChange } = this.props;

let className = '';
// Is this the currently selected option?
if (selected === option) {
// If so, let's give it a unique class for styling
className
= 'selected';
}

// Render our option
return this.renderOption(option, onChange, className);
}

renderOption
(option, onChange, className) {
if (!option) return null;

// Render the individual option as an <a/> element
return (
<a
key
={option}
onClick
={() => onChange(option)}
className
={className}
>
{option}
</a>
);
}

renderList
() {
// Grab the `expanded` property from this component's own state
const { expanded } = this.state;
// Grab our `options` array and `selected` props
// These are props passed to us by the parent
const { options, selected } = this.props;

// Did the user expand the menu?
if (expanded === true) {
// If so, take each `option` the parent passed in
// And render it using the `renderOption()` method
return options.map(this.generateOption.bind(this));
} else {
// If not, find the `option` matching our `selected` prop
// Then just render that element
return this.renderOption(
options
.find(option => option === selected),
this.toggleOptions,
'selected'
);
}
}

render
() {
// Grab the `labelText` prop
const { labelText } = this.props;

return (
<label className="form-dropdown">
<strong>{labelText}</strong>
<nav>{this.renderList()}</nav>
</label>
);
}
}

Observe que este componente está um pouco mais envolvido. Porém, não se esqueça do fator determinante! Um componente pode ter funcionalidade robusta e tudo isso pode ser , tornando-o um Componente Estúpido!Contextually Relevant

Então, o que torna um DropdownSmart?
Especificamente a expandedfuncionalidade.

Nossa lista suspensa pode ter optionsum formulário de endereço diferente onde seria preenchido com . Nesse caso, até mesmo o nosso precisaria chamar uma função específica que possa manipular o selecionado pelo usuário, em vez de escolher em uma lista em um formulário de busca de carros usados.States/ProvincesonChangeState/ProvinceMakes

Mas independentemente de estar ou não mostrando s ou s, nosso menu suspenso sempre precisará expandir ou recolher a lista para permitir que o usuário altere seu valor. Isso é inteiramente . Colocar essa funcionalidade nas mãos de um componente pai seria perigoso porque cada componente pai que usa o componente teria que copiar esse código , o que é incrivelmente ineficiente e leva a bugs e é difícil de manter o código.State/ProvinceMakeContextually IrrelevantDropdown

Contextual Irrelevance para construir aplicativos da web limpos e otimizados

Agora você sabe! Escrever componentes fáceis de manter, testar e usar é importante para garantir que seu aplicativo permaneça limpo e fácil de manter. Lembre-se de usar como forma de determinar se seu componente deve ser Inteligente ou Estúpido.Contextual Irrelevance

Nui é uma estrutura React que torna realmente fácil escrever aplicativos limpos e fáceis de manter. Fácil de usar para seu site pessoal, testado em empresas para aplicativos de produção. Ele remove muitos dos principais boilerplating necessários e possui renderização opcional do lado do servidor pré-configurada e integrada.

Guias de tópicos relacionados

  • Criando seu primeiro componente
  • Criando sua primeira página
  • Como funcionam as dependências
  • Exemplo de aplicativo Todo