React hooks: что / почему `useEffect`? - PullRequest
0 голосов
/ 29 октября 2018

Относительно недавно предложенного React Effect Hook ;

  1. Каковы преимущества и варианты использования крючка Effect (useEffect())?

  2. Почему это предпочтительнее и чем оно отличается от componentDidMount/componentDidUpdate/componentWillUnmount (производительность / читаемость)?

В документации указано, что:

Мутации, подписки, таймеры, ведение журнала и другие побочные эффекты не допускаются внутри основного тела функционального компонента (называемого фазой рендеринга React).

но я думаю, что уже было общеизвестно иметь такое поведение в методах жизненного цикла, таких как componentDidUpdate и т. Д. Вместо метода рендеринга.

Также есть упоминание, что:

Функция, переданная useEffect, запустится после фиксации рендера на экране.

но разве это не то, что componentDidMount & componentDidUpdate делает в любом случае?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018
  1. Каковы преимущества и варианты использования крючка Effect (useEffect())?

    Преимущества

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

    Вторым преимуществом (в частности, обработчиков эффектов) является предотвращение ошибок, которые могут возникнуть в противном случае, если зависящие от состояния побочные эффекты не обрабатываются должным образом в componentDidUpdate (поскольку обработчики эффектов гарантируют, что такие побочные эффекты установлены и разорваны). вниз на каждом рендере).

    См. Также преимущества производительности и читаемости, подробно описанные ниже.

    Варианты использования

    Любой компонент, реализующий логику с сохранением состояния с использованием методов жизненного цикла - ловушка Effect - это «Лучший путь».

  2. Почему это было бы предпочтительнее и чем оно отличается от componentDidMount / componentDidUpdate / componentWillUnmount (производительность / читаемость)?

    Почему это предпочтительнее

    Из-за преимуществ, описанных выше и ниже.

    Чем он отличается от методов жизненного цикла

    Performance

    Эффектные крючки -

    • чувствуют себя более отзывчивыми, чем методы жизненного цикла, потому что они не блокируют браузер от обновления экрана;
    • будет вызывать побочные эффекты для каждого рендера, которые могут быть дорогими.
    • & hellip; можно оптимизировать для полного пропуска, если не было обновлено определенное состояние.

    читаемость

    Эффектные зацепки приводят к:

    • Более простые и удобные в обслуживании компоненты благодаря способности разбивать несвязанное поведение, которое ранее должно было быть выражено в одном и том же наборе методов жизненного цикла, в один хук для каждого такого поведения, например:

      componentDidMount() {
        prepareBehaviourOne();
        prepareBehaviourTwo();
      }
      
      componentDidUnmount() {
        releaseBehaviourOne();
        releaseBehaviourTwo();
      }
      

      становится:

      useEffect(() => {
        prepareBehaviourOne();
        return releaseBehaviourOne;
      });
      
      useEffect(() => {
        prepareBehaviourTwo();
        return releaseBehaviourTwo;
      });
      

      Обратите внимание, что код, относящийся к BehaviourOne, теперь четко отделен от кода, относящегося к BehaviourTwo, тогда как до этого он был смешан в каждом методе жизненного цикла.

    • меньше стандартного шаблона, благодаря исключению необходимости повторять один и тот же код для нескольких методов жизненного цикла (например, обычно между componentDidMount и componentDidUpdate) - например:

      componentDidMount() {
        doStuff();
      }
      
      componentDidUpdate() {
        doStuff();
      }
      

      становится:

      useEffect(doStuff); // you'll probably use an arrow function in reality
      
0 голосов
/ 29 октября 2018

Вот пример из ReactConf2018 * Дана Абрамова , объясняющего разницу:


Вот несколько выводов из приведенного ниже примера:

  1. Вы будете писать меньше стандартного кода, используя хуки
  2. Доступ к обновлениям жизненных циклов и обновления состояний с помощью useEffect()
  3. Относительно исполнения один аспект:

В отличие от componentDidMount и componentDidUpdate, функция, переданная useEffect, запускается после разметки и рисования во время отложенного события

  1. Совместное использование кода будет слишком простым, и функция useEffect () может быть реализована несколько раз для разных целей в одном и том же компоненте.
  2. Вы можете более эффективно контролировать рендеринг компонента, передав массив в качестве второго аргумента хуку useEffect(), что очень эффективно, когда вы просто передаете пустой массив [] для рендеринга компонента только при монтировании и размонтировании.
  3. Используйте несколько useEffect() крючков для разделения проблем и отреагируйте следующим образом:

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


Использование классов:

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }

  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

Использование крючков:

import { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
...