Исправьте осанку, используя API контекста реагирования

React.js

В этой статье рассказывается, как использовать общий Context API в React. Прежде чем использовать Context API, нам также нужно знать, почему. ❓

Зачем использовать контекстный API

По компонентам можнослои вложения, в процессе прохождения реквизита, если много писать...propsилиpropName={this.props.propValue}Приведет к очень уродливому коду 🤢:

20190312085239.png

Слой за слоем это происходит так:

<App>
    <Switcher toggleState={this.state.toggle}>
        <Pannel toggleState={props.toggleState}>
            <div onClick={handleClick}>{props.toggleState ? '✔' : '❌'}

Поэтому, внедрив Context API, данные можно получать напрямую через контекст через уровни:

как использовать

  • Затем создайте провайдера 👇
  • Первое, что нужно сделать, это представить встроенный React Context API 📦
  • Наконец создайте потребителя 👆

Создать провайдера

добавитьToggleContext.jsфайл как контекст📜, который определяет ряд состояний и функций, которые необходимо использовать на разных уровнях.

import React, { createContext } from 'react'

// 1. 使用 createContext 创建上下文
const ToggleContext = createContext({
    toggle: true,
    handleToggle: () => {}
})

// 2. 创建 Provider
export class ToggleProvider extends React.Component {

    // 注意书写顺序;handleToggle 作为箭头函数不能 bind 因此需要写在上面;如果不喜欢这样的顺序则可以书写普通函数放在下面但记得 bind
    handleToggle = () => {
        this.setState({ toggle: !this.state.toggle })
    }

    // 2-1. 重写 state 
    state = {
        toggle: true,
        handleToggle: this.handleToggle
    }

    render() {
        // 2-2. 通过 Provider 组件的 value 将 state 提供出去
        return (
            <ToggleContext.Provider value={this.state}>
                {this.props.children}
            </ToggleContext.Provider>
        ) 
    }
}

// 3. 创建 Consumer
export const ToggleConsumer = ToggleContext.Consumer

Приведенный выше код в основном разделен на три части:

// 创建 Context
const ToggleContext = createContext()

// 创建 Provider
export class ToggleProvider extends React.Component {}

// 创建 Consumer
export cnost ToggleConsumer = ToggleContext.Consumer

Пройдёмся по шагам 🏃‍

  • Во-первых, нам нужно представитьcreateContextконтекст и вызов, передавая то, что мы хотим использовать в других иерархических компонентахstateи изменитьstateметод, обратите внимание наstateа методы это всего лишь "скелет", последниеProviderбудет охватывать
  • Далее создайтеProviderОтправляйтесь сюда, чтобы сохранить настоящуюstate, и пройтиrenderвнутри функцииContext.Providerкомпонентvalueсвойства предоставляют эти методы
  • затем создайтеConsumer, экспортировать напрямуюContext.Consumerдля наружного применения

использовать провайдера

ToggleProviderКомпонент оборачивает набор общего состояния, и чтобы использовать состояние компонента, мы добавляем его непосредственно в компонент приложения:

import React from 'react';
import { ToggleProvider } from './ToggleContext' // 1. 获取 Provider

function App() {
  // 2-1. 使用 ToggleProvider 组件
  // 2-2. 如果有其他组件一样可以共享 state
  return (
    <ToggleProvider>
      <Switcher></Switcher>
      {/* 其他组件仍然可以通过 props 访问到共享的 state */}
    </ToggleProvider>
  );
}

// ...
export default App;

Относительно просто использовать Provider непосредственно в качестве родительского компонента и обернуть его в верхний уровень. Если внутри компонента есть несколько других компонентов, эти компоненты могут совместно использовать состояние, предоставленное поставщиком.

Использовать потребительский

  • Вы можете напрямую использовать свойство состояния, переданное реквизитами, для рендеринга в функции рендеринга через Consumer
  • Если вам нужно вызвать метод, вы можете вызвать функцию, переданную реквизитами
import React from 'react';
import { ToggleProvider, ToggleConsumer } from './ToggleContext' // 1. 获取 Provider 和 Consumer

function App() {
  return (
    <ToggleProvider>
      <Switcher></Switcher>
    </ToggleProvider>
  );
}

const Switcher = () => {
  return <Pannel />
}

const Pannel = () => {
  // 在多个层级内直接通过 props 获取 state 和方法,调用方法改变 state
  return (
    <ToggleConsumer>
      {({ toggle, handleToggle }) => <div onClick={() => handleToggle()}>{ toggle ? '✔' : '❌'}</div>}
    </ToggleConsumer>
  )
}

export default App;

Непосредственно в рамках сборки может быть вызван реквизитом

резюме

Кроме того, прилагается упрощенная версия Context:

  • Создайте контекст с именем цвета через createContext
  • Передайте значение через свойство value поставщика.
  • Получать значения через Consumer props
import React, { createContext } from "react";

const { Provider, Consumer } = createContext("color"); // 创建 Context 引用 Provider 和 Consumer

class DeliverComponent extends React.Component {
  // 维护一个 state
  state = {
    color: 'orange',
    handleClick: () => {
      this.setState({ color: 'red' })
    }
  }
  render() {
    return (
      <Provider value={this.state}>
        <MidComponent />
      </Provider>
    )
  }
}

const MidComponent = () => <Receiver />; // 中间包含多层级的组件

const Receiver = () => ( // 需要使用的后代元素使用 Consumer
  <Consumer>
    {({ color, handleClick }) => <div style={{ color }} onClick={() => { handleClick() }}> Hello, this is receiver.</div>}
  </Consumer>
);

const App = () => <DeliverComponent />;

export default App;

Ссылаться на:

  • https://blog.usejournal.com/sharing-state-using-reacts-context-api-bc2db94da46d