Есть ли способы смоделировать componentDidMount в функциональных компонентах React с помощью хуков?

jeyko

Ответы (10)

Для стабильной версии хуков (React Version 16.8.0 +)

Для componentDidMount

useEffect(() => {
  // Your code here
}, []);

Для componentDidUpdate

useEffect(() => {
  // Your code here
}, [yourDependency]);

Для componentWillUnmount

useEffect(() => {
  // componentWillUnmount
  return () => {
     // Your code here
  }
}, [yourDependency]);

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

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

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

useEffect(() => {
  // 
{count}
}, [count]);

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

import React, { 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 (
    

You clicked {count} times

); }

Пожалуйста, посетите эту официальную документацию. Очень легко понять последний способ.

https://reactjs.org/docs/hooks-effect.html

ComponentDidMount

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

Информация об асинхронных функциях внутри хука:

Обратные вызовы эффектов синхронны, чтобы предотвратить состояние гонки. Поместите асинхронную функцию внутрь:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
}, [someId]); // Or [] if effect doesn't need props or state

Вы хотите использовать useEffect (), который, в зависимости от того, как вы используете функцию, может действовать так же, как componentDidMount ().

Например. вы можете использовать настраиваемое свойство состояния loaded, для которого изначально установлено значение false, и переключить его на true при рендеринге и активировать эффект только при изменении этого значения.

Документация

В функциональных компонентах нет componentDidMount, но перехватчики React предоставляют способ эмуляции поведения с помощью перехватчика useEffect.

Передайте пустой массив в качестве второго аргумента функции useEffect (), чтобы запускать только обратный вызов только при монтировании.

Пожалуйста, прочтите документацию по useEffect.

function ComponentDidMount () {
  const [количество, setCount] = React.useState (0);
  React.useEffect (() => {
    console.log ('componentDidMount');
  }, []);

  возвращение (
    

componentDidMount: {count} раз

кнопка < onClick = {() => { setCount (счетчик + 1); }} > Нажми на меня
); } ReactDOM.render (
, document.querySelector ("# приложение") );



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

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

Возьмем, к примеру,

function App() {
  const [appointments, setAppointments] = useState([]);
  const [aptId, setAptId] = useState(1);

  useEffect(() => {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = aptId;
          console.log(aptId);
          setAptId(aptId + 1);
          return item;
        })
        setAppointments(apts);
      });
  }, []);

  return(...);
}

и

class App extends Component {
  constructor() {
    super();
    this.state = {
      appointments: [],
      aptId: 1,
    }
  }

  componentDidMount() {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = this.state.aptId;
          this.setState({aptId: this.state.aptId + 1});
          console.log(this.state.aptId);
          return item;
        });
        this.setState({appointments: apts});
      });
  }

  render(...);
}

Это только для примера. так что давайте не будем говорить о передовых методах работы или потенциальных проблемах с кодом. И то, и другое имеет одинаковую логику, но последнее работает только так, как ожидалось. Вы можете получить функциональность componentDidMount с запущенным useEffect в это время, но по мере роста вашего приложения есть вероятность, что вы МОЖЕТЕ столкнуться с некоторыми проблемами. Так что вместо того, чтобы переписывать на этом этапе, лучше сделать это на ранней стадии.

Кроме того, ООП не так уж и плох, если бы было достаточно процедурно-ориентированного программирования, у нас никогда не было бы объектно-ориентированного программирования. Иногда это больно, но лучше (технически не говоря уже о личных проблемах).

useEffect () hook позволяет нам достичь функциональности componentDidMount, componentDidUpdate, componentWillUnMount функциональности.

Различные синтаксисы useEffect () позволяют реализовать каждый из вышеперечисленных методов.

i) componentDidMount

useEffect (() => {
  // код здесь
}, []);

ii) componentDidUpdate

useEffect (() => {
  // код здесь
}, [x, y, z]);

// где x, y, z - переменные состояния, при обновлении которых этот метод должен срабатывать

iii) componentDidUnmount

useEffect (() => {
  // код здесь
  return function () {
    // код для запуска на этапе размонтирования
  }
}, []);

Дополнительную информацию можно найти на официальном сайте реакции.Официальная страница React на хуках

точный эквивалент хука для componentDidMount ():

useEffect(()=>{},[]);

надеюсь, что это поможет :)

Не существует точного эквивалента для componentDidMount в перехватчиках реакции.


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

С учетом сказанного, есть способы, которыми вы можете использовать хуки для получения аналогичного эффекта от до componentDidMount.

Решение 1:

useEffect (() => {
  console.log («Меня примонтировали»)
}, [])

Решение 2:

const число = 5

useEffect (() => {
  console.log ("Я буду работать, только если мои данные изменятся:", num)
}, [число])

Решение 3 (с функцией):

useEffect (() => {
  const someFunc = () => {
    console.log ("Функция, запускаемая после / при монтировании")
  }
  someFunc ()
}, [])

Решение 4 (useCallback):

const msg = "какое-то сообщение"

const myFunc = useCallback (() => {
  console.log (сообщение)
}, [сообщение])

useEffect (() => {
  myFunc ()
}, [myFunc])

Решение 5 (творческий подход):

функция экспорта по умолчанию useDidMountHook (callback) {
  const didMount = useRef (нуль)

  useEffect (() => {
    if (callback &&! didMount.current) {
      didMount.current = правда
      Перезвони()
    }
  })
}

Стоит отметить, что решение 5 действительно следует использовать только в том случае, если ни одно из других решений не подходит для вашего варианта использования. Если вы все же решите, что вам нужно решение 5, я рекомендую использовать этот готовый крючок use-did-mount.

Источник (с более подробной информацией): Использование componentDidMount в перехватчиках реакции

2022 WebDevInsider