Подробные функции реагирования высшего порядка (включая яйца)

React.js

Эта статья подходит для новичков в реагировании, а реактбосс может ее пропустить (ведь раньше я писал vue, а React только больше месяца писал, а я закрывал лицо и плакал)

В основном, чтобы узнать немного об опыте реакции, если вы считаете, что это полезно для вас, вы можете поставить лайкgithub.

Начало работы с реактивными проектами

Версия React: 16.0.0 (поскольку это все еще рабочая версия 15)

Сначала поговорим о компонентах с состоянием и компонентах без состояния.

Компоненты с сохранением состояния Компоненты без состояния

Компоненты с отслеживанием состояния: внутреннее состояние компонента изменяется, и это состояние необходимо для сохранения изменений.

Компонент без состояния: внутреннее состояние компонента не изменяется, и состояние не используется.Рекомендуется писать функциональные компоненты

Идея проектирования компонентов: управляйте изменениями состояния всего приложения, определяя несколько компонентов с состоянием и передавая состояние остальным компонентам без состояния через реквизиты.

Компоненты с состоянием в основном сосредоточены на бизнес-логике обработки изменений состояния, а компоненты без состояния в основном сосредоточены на рендеринге пользовательского интерфейса компонента. Это больше способствует повторному использованию компонентов, а разделение между компонентами является более тщательным.

Иногда это создает проблему, а что, если вы добавите другую логику в компоненты пользовательского интерфейса?

2 лучших метода, this.props.children и HOC,конкретные примеры. Итак, давайте подробно поговорим о компонентах высокого порядка HOC.

Обязательное условие знаний:

Шаблон оформления декоратора: позволяет добавлять новые функции к существующему объекту без изменения его структуры. Этот тип шаблона проектирования представляет собой структурный шаблон, который действует как оболочка существующего класса.

Этот шаблон создает оформленный класс, который является оболочкой исходного класса и предоставляет дополнительные функции, сохраняя при этом целостность сигнатур методов класса.

Компоненты высшего порядка HOC (общая логика, которая инкапсулирует и разделяет компоненты. По сути, это применение шаблона проектирования декоратора)

  • основная концепция:

В JS функции высшего порядка могут принимать функцию в качестве параметра и возвращать значение в виде функции, которая также является функцией. Подобные компоненты более высокого порядка также могут принимать компонент в качестве параметра и возвращать обработанный компонент.

По сути, функция высшего порядка — это функция, а не компонент.

  • используемые сцены:
  1. Управление реквизитом
  2. Доступ к экземпляру компонента по ссылке
  3. улучшение состояния компонента
  4. Оберните компоненты другими элементами

пример:

  1. Манипулирование реквизитом используется больше

До того, как обернутый компонент получит props. Компоненты более высокого порядка могут сначала перехватывать реквизиты, выполнять такие операции, как добавление, удаление и изменение реквизитов, а затем передавать измененные реквизиты упакованному компоненту.

import React, { Component } from 'react'

function withPersistentData (wrapedComponent) {
  return class extends Component {
    componentWillMount() {
      let data = localStore.getItem('data');
      this.setState({data})
    }

    render () {
      const { data } = this.state;
      // 通过{...this.props} 把传给当前组件的值继续传给被包装的组件
      return <wrapedComponent data={data} {...this.props} />
    }
  }
}

@withPersistentData
export default class myComponent extends Component {
  render() {
    return (
      <div>
        {this.props.data}
      </div>
    )
  }
}

  1. Доступ к экземплярам компонентов осуществляется через ref. Я редко использую это использование.

Компонент более высокого порядка получает ссылку на экземпляр упакованного компонента через ref, а затем компонент более высокого порядка получает возможность напрямую манипулировать свойствами и методами упакованного компонента.

function withRef (wrapedComponent) {
  return class extends Component {
    someMethod = () => {
      // this.wrapedComp        被包装组件实例 
      // someMethodWrapedComp   被包装组件的方法
      this.wrapedComp.someMethodWrapedComp()
    }

    render () {
      // 通过{...this.props} 把传给当前组件的值继续传给被包装的组件
      // 给被包装的组件添加ref属性,获取被包装组件实例并赋值给this.wrapedComp
      return <wrapedComponent ref={(comp) =>{this.wrapedComp = comp}} {...this.props} />
    }
  }
}
  1. улучшение состояния компонента

Как упоминалось выше, компоненты без состояния легче повторно использовать.Мы можем использовать компоненты более высокого порядка для равномерного обновления состояния, которое необходимо поддерживать в исходных контролируемых компонентах, до компонентов более высокого порядка, а контролируемые компоненты не имеют состояния.

import React, { Component } from 'react'

function withControlledComp(wrappedComp) {
  state = {
    value : null,
  }
  handleValueChange = (e) => {
    this,setState({value: e.target.value})
  }

  render () {
    const newProps ={
      controlledProps: {
        value: this.state.value,
        onChange: this.handleValueChange
      }
    }
    return <wrappedComp {...this.props} {...newProps} />
  }
}

@withControlledComp
class ControlledComp extends Component {
  render () {
    // 此时的受控组件为无状态组件,状态由高阶组件控制
    return <input {...this.props.controlledProps} />
  }
}
  1. Оберните компоненты другими элементами
function withRedColor (wrapedComponent) {
  return class extends Component {
    render () {
      return (<div style={color: 'red}><wrapedComponent {...this.props} /> </div>)
    }
  }
}



* Передача параметров Помимо приема компонентов, параметры компонентов более высокого порядка также могут принимать другие параметры.

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

Обычно мы используем этот метод: HOC(...params)(wrappedComp)

function withPersistentData = (key) => (wrapedComponent) => {
  return class extends Component {
    componentWillMount() {
      let data = localStore.getItem(key);
      this.setState({data})
    }

    render () {
      const { data } = this.state;
      // 通过{...this.props} 把传给当前组件的值继续传给被包装的组件
      return <wrapedComponent data={data} {...this.props} />
    }
  }
}

class myComponent extends Component {
  render() {
    return (
      <div>
        {this.props.data}
      </div>
    )
  }
}

// 获取key=‘data’的数据
const myComponentWithData = withPersistentData('data')(myComponent)

// 获取key=‘name’的数据
const myComponentWithData = withPersistentData('name')(myComponent)

Фактически, эта форма компонентов более высокого порядка появляется в большом количестве сторонних библиотек, таких как функция подключения в react-redux.

connect(mapStateToProps, mapDispatchToProps)(wrappedComponent)



* Меры предосторожности
  1. Не используйте компоненты более высокого порядка в рендеринге и старайтесь не использовать компоненты более высокого порядка в других функциях жизненного цикла. Поскольку компонент более высокого порядка каждый раз возвращает новый компонент, при каждом рендеринге ранее созданный компонент будет выгружаться, а компонент, созданный на этот раз, будет перемонтироваться.
  2. Если вам нужно использовать статические методы обернутого компонента, вы должны скопировать эти методы вручную. Потому что компоненты более высокого порядка не содержат статических методов обернутого компонента.
  3. Ссылки не передаются обратно обернутому компоненту.
  4. Отличие от родительского компонента. Если эта часть логики связана с UI/DOM, то эта часть логики подходит для реализации в родительском компоненте, если логика не связана напрямую с DOM, то эта часть логики подходит для абстракции компонентов более высокого порядка. Например, отправка запроса на проверку данных и т. д.

Пасхальное яйцо здесь, а пасхальное яйцо — это сцена использования жизненного цикла реакции, хахахаха, сюрприз или сюрприз.

Жизненный цикл компонента React и сценарии использования

горная сцена

1. constructor
2. componentWillMount
3. render
4. componentDidMount

сцены, которые будут использоваться

1. coustructor  
  通常用于初始化组件的state以及绑定事件的处理方法(比如bind(this))等

2. componentWiillMound
  在组件被挂载到DOM前调用,且只会调用一次,
  实际项目中比较少用到,因为可以在该方法中的执行的都可以提到coustructor中
  在这个方法中this.setState不会引起重新渲染

3. render
  渲染方法。
  注意:render只是返回一个UI的描述,真正渲染出页面DOM的工作由react自己完成
  
4. componentDidMount
  在组件被挂载到DOM后调用,且只会调用一次,
  通常用于像后端请求数据
  在这个方法中this.setState会引起组件的重新渲染

фаза обновления

1. componentWillReceiveProps
2. shouldComponentUpdate
3. componentWillUpdate
4. render
5. componentDidUpdate

сцены, которые будут использоваться

1. componentWillRceiveProps(nextProps)
  这个方法只在props引起组件更新时调用。
  一般会比较一下this.props和nextProps来决定是否执行props变化后的逻辑
  比如:根据新的props调用this.setState来触发组件的重新渲染

2. shouldComponentUpdate(nextProps,nextState)
  这个方法决定组件是否继续执行更新过程。 
  默认是true,继续更新;false阻止更新。
  一般是通过比较nextPops,nextState和当前组件的props,state来决定返回结果。 
  这个方法可以减少不必要的渲染,优化组件性能。
  原因:根据渲染流程,首先会判断shouldComponentUpdate是否需要更新。如果需要更新,调用render方法生成新的虚拟DOM与旧的虚拟DOM进行对比(render只是返回一个UI描述),如果对比不一致,则根据最小粒度改变去更新DOM。

3. componentWillUpdate
  render前调用,组件更新前执行某些逻辑的地方。
  一般很少用到。

4. render

5. componentDidUpdate(prevProps, prevState)
  组件更新后被调用,可以作为操作更新后DOM的地方。
  这个方法中的prevProps和prevState代表组件中更新前的props和state。

注意:在render前的生命周期中,componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate中的this.state依然指向更新前的state。

фаза разрушения

componentWillUnmount
  组件卸载前被调用。
  清除定时器,清除componentDidMount中手动创建的DOM,取消请求等

заключительные замечания

Наконец, спасибо друзьям, которые могут видеть здесь, потому что уровень ограничен, пожалуйста, поправьте меня, если есть какие-либо ошибки, я очень благодарен.

Ссылаться на:
Реагировать на продвинутую дорогу