Usar ganchos no React Native

A React anunciou oficialmente que o React v16.7.0-alpha (Beta) apresentará Hooks na conferência ReactConf de 2018. O que é Hooks, vamos descobrir.

O que são ganchos?

No processo de desenvolvimento usual, geralmente encontramos os seguintes problemas:

1. É difícil reutilizar e compartilhar a lógica relacionada ao estado
nos componentes 2. Os componentes lógicos complexos são difíceis de desenvolver e manter Quando nossos componentes precisam lidar com vários estados não relacionados, cada função do ciclo de vida pode conter Várias lógicas não relacionadas estão dentro.
3. Devido a mudanças nos negócios, os componentes de função precisam ser alterados para componentes de classe e assim por diante.

O texto acima é mais abstrato: a seguir, usaremos o teclado da API como um exemplo para ilustrar o problema.

export default class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      isShowKeyboard: false
    }
  }

  static getDerivedStateFromProps() {
    this.keyboardDidShowListener = Keyboard.addListener(
      "keyboardDidShow",
      this.keyboardDidShowHandler
    );
  }

  keyboardDidShowHandler () {
    this.setState({
      isShowKeyboard: true
    });
  }

  componentWillUnmount() {
    this.keyboardDidShowListener.remove();
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>
          当前键盘状态: {this.state.isShowKeyboard}
        </Text>
      </View>
    );
  }
}

O caso de uso do código acima é relativamente simples, use o Teclado para se registrar para monitorar a exibição e o estado oculto do teclado . Você pode ver o registro, o logout e a renderização do estado do evento do teclado serem colocados no Component.Se muita dessa lógica estiver envolvida no Component atual, ele fará com que o Component atual tenha responsabilidades muito pesadas e os dados do estado não poderão ser compartilhados. Quando você precisa monitorar eventos do teclado, é necessário reescrever ou copiar código duplicado.A redundância é muito séria e não é uma boa coisa para manutenção e expansão de funções.

O surgimento de Hooks resolve o problema acima: permite que os desenvolvedores definam componentes de função e também pode usar o estado e o ciclo de vida dos componentes de classe, sem a necessidade de alternar entre mixins, componentes de função, componentes HOC e objetos de renderização. Switch. É conveniente realizarmos a separação do código da lógica de negócios e a reutilização de componentes nos negócios. Comparado ao uso de setState, os componentes são sem estado. Vamos ver como usar Hooks:

import { useState, useEffect } from 'react';
import {
    Keyboard
} from 'react-native';

export default function keyboard() {
    const [keyboardStatus, setKeyboardStatus] = useState(false);
    Keyboard.addListener(
        "keyboardDidShow",
        this.keyboardDidShowHandler
    );
    useEffect(()=> {
        return ()=> Keyboard.removeListener(
            "keyboardDidShow",
            ()=> setKeyboardStatus(true)
        );
    }, [false]);
    return (
        <Text>
            当前键盘状态:{keyboardStatus}
        </Text>
    )
}

No código acima, a lógica de negócios sobre o teclado é desfeita em funções, chamadas  componentes de função. Quando o usamos em outros componentes, precisamos apenas importá-lo. No componente function, usamos useState e useEffect.Que papel eles desempenham como APIs fornecidas no Hooks?

Hooks Api

O funcionário fornece três APIs principais de ganchos, como Ganchos de Estado, Ganchos de Efeito, Ganchos de Contexto, Ganchos Personalizados (ganchos personalizados).

useState

useState Esse método pode trazer o estado local para o componente de função, ele recebe um valor para o estado inicial e retorna um par de variáveis

// 等价于
const keyboardStatus= useState(0)[0];
const setKeyboardStatus= useState(0)[1];

É relativamente simples entender, de fato, é definir o valor do estado do estado e modificar a função de comportamento do valor do estado do estado.

useEffect

useEffect pode ser simplesmente entendido como um substituto para o seguinte ciclo de vida:

componentDidMount, componentDidUpdate, componentWillUnmount 

O código de useEffect será executado não apenas durante a primeira inicialização (componentDidMount), mas também sempre que uma renderização subsequente for acionada (componentDidUpdate), e o valor de retorno será executado quando o componente não estiver registrado (componentWillUnmount). Combinado com o exemplo acima:

useEffect(()=> {
   // return 将会在组件注销时调用
   return ()=> Keyboard.removeListener(
       "keyboardDidShow",
       ()=> setKeyboardStatus(true)
   );
}, [false]);

O segundo parâmetro de useEffect, como uma configuração de otimização de desempenho, decide se é necessário executar as operações internas para evitar algumas perdas desnecessárias de desempenho. Enquanto o valor do membro na segunda matriz de parâmetros não for alterado, essa execução será ignorada. Se uma matriz vazia [] for passada, ela será executada apenas durante a montagem e desmontagem de componentes.

Ganchos de Contexto

Uma nova API de contexto foi lançada no React 16.3. O objetivo é resolver o problema de que o nível de aninhamento dos componentes filho é muito profundo e as propriedades dos componentes pai são difíceis de se comunicar. O método de uso não é complicado: primeiro, use a API de contexto para criar um provedor de dados (provedor) e um consumidor de dados (consumidor). (Falando nisso é um pouco como o exemplo da simultaneidade multithread Java). Armazene dados no local em que o provedor está localizado e busque os dados em que o consumidor está localizado. Dê uma olhada em como o Contexto é usado:

(1) Criar contexto

// 创建 Context
import React from 'react';
const DataContext = React.createContext({
    name: '',
    age: 23
});
export default DataContext;


(2) Defina o provedor do provedor de dados

export default class App extends Component {

  render() {
    return (
      <DataContext.Provider value={{ name: 'Songlcy', age: 27 }}>
        <CustomComponent />
      </DataContext.Provider>
    );
  }
}

(3) Definir consumidor

export default class CustomComponent extends Component {
    render() {
        return (
            <DataContext.Consumer>
                {
                    context => (
                        <Text>
                            我的名字:{context.name}, 我的年龄:{context.age}
                        </Text>
                    )
                }
            </DataContext.Consumer>
        )
    }
}

Quando o nível de aninhamento de componentes for profundo, as vantagens do Contexto serão mais óbvias.

" Eh, acorde! " ... disse muito, continue voltando a Hooks. No código acima, os dados são obtidos do Contexto - Provedor - Consumidor , e todo o processo de valor é relativamente entediante. Quando queremos obter valores de vários  consumidores , é ainda mais problemático aninhar funções.

useContext é uma simplificação da API de contexto. Vamos ver como fica depois da simplificação:

const { name, age } = useContext(DataContext);

" Eu confio! É este o fim? " Sim, o processo de valor é tão simples e caprichoso.  Que tal mais 10  consumidores !

Ganchos personalizados

Ganchos personalizados é um comportamento de ganchos personalizado, que não é uma API em si. O conceito principal é extrair a lógica e encapsulá-la na função.A implementação específica é encapsular a lógica relacionada aos dados do estado (Estado) por meio de uma função e extrair essas lógicas do componente. Nesta função, podemos usar outros ganchos ou testá-lo separadamente. Modifique o exemplo acima:

export default function useKeyboardStatus() {
    const [keyboardStatus, setKeyboardStatus] = useState(false);
    Keyboard.addListener(
        "keyboardDidShow",
        this.keyboardDidShowHandler
    );
    useEffect(()=> {
        return ()=> Keyboard.removeListener(
            "keyboardDidShow",
            ()=> setKeyboardStatus(true)
        );
    },[]);
    return keyboardStatus;
}

Código é quase idêntico, a única diferença é o nome da função com o uso * prefixo aqui precisa seguir uma convenção, chamado uso  uso * .

Como funcionam os ganchos

"Shenma? Hooks é na verdade uma matriz !"

Lembre-se da maneira como usamos o useState inicialmente:

const [keyboardStatus, setKeyboardStatus] = useState(false);

De fato, a partir deste código, também podemos adivinhar a ideia geral de implementação:

Use uma  função do tipo setter para retornar como o segundo item do array na função hook, e o setter controlará o estado gerenciado pelo hook (State), e o estado será retornado pelo primeiro item do array.

Podemos entender que existem duas matrizes, que armazenam respectivamente métodos correspondentes a state e setState.

Quando useState () é executado pela primeira vez, a função setter é enviada para a matriz setter e o estado é enviado para a matriz state. Cada setter tem uma referência à sua posição do cursor; portanto, ao acionar uma chamada para qualquer setter, ele altera o valor do estado nessa posição na matriz de estados. Para simplificar, existe um índice e o método setter modifica o valor dos dados do estado correspondente de acordo com o índice. Vamos dar uma olhada na implementação do pseudocódigo:


let state = []; // 存放state状态数据
let setter = []; // 存放 setXXX方法
let initial = true; // 是否是第一次运行
let index = 0;


useState(initVal) {
  if (initial) {
    state.push(initVal);
    setter.push(createSetter(index));
    initial = false;
  }

  const setter = setter[index];
  const value = state[index];

  index++;
  return [value, setter];
}


createSetter(index) {
  return function setterWithIndex(newVal) {
    state[index] = newVal;
  };
}

A implementação específica do código fonte, todos os interessados ​​podem ir e ver. No entanto, não é recomendável entender todas as etapas, apenas entender a ideia de realização.

Sumário

O estado e a lógica de processamento relacionada podem ser divididos de acordo com a função, sem a necessidade de serem dispersos em cada ciclo de vida, o que reduz bastante a dificuldade de desenvolvimento e manutenção. Além desses ganchos, existem outros ganchos adicionais: Referência da API de ganchos

Por fim, recomende duas bibliotecas muito boas:

react-use encapsula vários ganchos.

eslint-plugin-react-hooks Ganchos ESLint 插件

Um artigo muito bom sobre o React Native Hooks, escrito por um estrangeiro: Noções básicas sobre o React Hooks - Criando um aplicativo React Native com ganchos do React

 

Publicado 214 artigos originais · elogiou 371 · 920.000 visualizações

Acho que você gosta

Origin blog.csdn.net/u013718120/article/details/88535116
Recomendado
Clasificación