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

Аналогия, что значит быть одинаковым?

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

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

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

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

/* JavaScript code */
const JohnnyDepp = {
  faceShape: 'diamond',
  eyeColor: 'blue',
};
const JohnnyDeppLookAlike = {
  faceShape: 'diamond',
  eyeColor: 'blue',
};

JohnnyDepp и JohnnyDeppLookAlike имеют одинаковые значения, но они НЕ одинаковы, как два похожих человека.

/* JavaScript code */
const JohnnyDepp = {
  faceShape: 'diamond',
  eyeColor: 'blue',
};
const JohnnyDeppReference = JohnnyDepp;

JohnnyDeppReference — это просто ссылка на оригинального JohnnyDepp, это невозможно описать людьми. Это один человек, упомянутый в двух местах. Два ярлыка ссылаются на один один и тот же документ в разных местах.

Я не хочу выполнять повторяющуюся работу, я хочу прочитать разные документы только один раз.

Заключение

  • Хуки проверяют ссылки, если два объекта одинаковы.
  • Два объекта с одинаковыми значениями не одинаковы.

Вопрос: Когда мой крючок побежит?

Ответ: При изменении значения в массиве зависимостей.

Вопрос: Что делать, если у меня нет массива зависимостей?

Ответ: Хук будет запускаться при изменении состояния любого компонента.

Время тестирования

С объяснением того, что такое ссылка и как она работает, и что я не хочу делать повторяющуюся работу. Точно так же, как хуки определяют, будут ли они работать или нет, я хочу видеть, когда мой хук будет работать.

Требования к испытаниям

/* JavaScript comment
 * ------------------
 *
 * Test which hook is called when dependency array changes.
 *
 * For example:
 *  - Component has states:
 *    1. A
 *    2. B
 *  - Component has two hooks
 *    1. First hook has dependency to A, shown below:
 *      - useEffect(() => {}, [A]);
 *    2. Second hook has dependency to B, shown below:
 *      - useEffect(() => {}, [B]);
 *  - Component has hook without dependency array to see when 
 *    it will be ran.
 *  - Change state A, but state B remains the same.
 *    # DOES HOOK WITH DEPENDENCY B RUN OR NOT?
 *    # DOES -- ONLY -- HOOK WITH DEPENDENCY A RUN?
*/

Код, реализующий предыдущие требования

/* React code */
function Test1() {
  const [a, setA] = useState(0);
  const [b, setB] = useState(0);
  const incrementA = () => {
    setA(previousA => previousA + 1);
  };
  const incrementB = () => {
    setB(previousB => previousB + 1);
  };
  useEffect(() => {
    console.log('Hook without dependency array: ', a, b);
    return () => {
      console.log('Cleanup from hook without dependency array')
    };
  });
  
  useEffect(() => {
    console.log('Hook with dependency A: ', a);
    return () => {
      console.log('Cleanup from hook with dependency A')
    };
  }, [a]);
  useEffect(() => {
    console.log('Hook with dependency B: ', b)
    return () => {
      console.log('Cleanup from hook with dependency B');
    };
  }, [b]);
  return (
    <section>
      <h1>
        Test which hook is called when dependency array changes.
      </h1>
      <section>
        <h1>Increment value A</h1>
        <p>Current value A is {a}</p>
        <button onClick={incrementA}>
          Click to increase value A by 1
        </button>
      </section>
      <section>
        <h1>Increment value B</h1>
        <p>Current value B is {b}</p>
        <button onClick={incrementB}>
          Click to increase value B by 1
        </button>
      </section>
    </section>
  );
}

Дело 1

Когда компонент появляется, вывод выглядит следующим образом:

/* javascript console output */
1. Hook without dependency array: 0 0
2. Hook with dependency A: 0
3. Hook with dependency B: 0

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

Случай 2

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

/* javascript console output */
1. Cleanup from hook without dependency array
2. Cleanup from hook with dependency A
3. Hook without dependency array: 1 0
4. Hook with dependency A: 1

Хук с массивом зависимостей, содержащим B, не запускался, потому что он не изменился.

Случай 3

Когда мы нажимаем кнопку Нажмите, чтобы увеличить значение B на 1, вывод будет следующим:

/* javascript console output */
1. Cleanup from hook without dependency array
2. Cleanup from hook with dependency B
3. Hook without dependency array: 1 1
4. Hook with dependency B: 1

Хук с массивом зависимостей, содержащим A, не запускался, потому что он не изменился.

Заключение

  • Когда компонент появится в первый раз, хук выполнится.
  • Когда значение массива зависимостей изменится, очистка будет выполняться и после этого перехватываться.
  • Хуки, у которых есть массив зависимостей, будут запускаться ТОЛЬКО при изменении их зависимости.
  • Когда компонент исчезает, выполняются все очистки.

Код можно найти здесь https://codepen.io/Flexos96/pen/RwjXEzb?editors=0010.

Присоединяйтесь к FAUN: Сайт💻|Подкаст🎙️|Twitter🐦|Facebook👥 |Instagram📷|Группа Facebook🗣️|Группа Linkedin💬| Slack 📱|Cloud Native Новости📰|Дополнительно.

Если этот пост был полезен, пожалуйста, несколько раз нажмите кнопку аплодисментов 👏 ниже, чтобы выразить свою поддержку автору 👇