реагировать на проблему закрытия крючков - PullRequest
0 голосов
/ 07 января 2020

enter image description here

завершить демонстрацию воспроизведения: https://github.com/leftstick/hooks-closure-issue

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

import { useState, useMemo, useCallback } from "react";
import { createModel } from "hox";

function testHooks() {
  const [users, setUsers] = useState([
    {
      id: "a",
      name: "hello"
    }
  ]);

  const removeUser = useCallback(
    user => {
      return new Promise(resolve => {
        setTimeout(() => {
          // async work here
          setUsers(users.filter(u => u.name !== user.name));
          resolve();
        }, 10);
      });
    },
    [users]
  );

  const addUser = useCallback(
    user => {
      return new Promise(resolve => {
        setTimeout(() => {
          // async work here
          // users here is not up-to-date
          setUsers([...users, user]);
          resolve();
        }, 10);
      });
    },
    [users]
  );

  //modify user = remove old-user + add new-user
  const modifyUser = useCallback(
    (oldUser, newUser) => {
      return new Promise((resolve, reject) => {
        removeUser(oldUser)
          .then(() => {
            // addUser relies on latest users updated by removeUser
            // but due to closure issue, it refers to original value
            // what is the best approach to achieve the expected behivour?
            return addUser(newUser);
          })
          .then(resolve, reject);
      });
    },
    [users]
  );

  return {
    users,
    modifyUser
  };
}

export default createModel(testHooks);

1 Ответ

0 голосов
/ 07 января 2020

Как и this.setState для компонентов на основе классов функциональная версия сеттера спасает день

const removeUser = 
    user => {
      return new Promise(resolve => {
        setTimeout(() => {
          setUsers(users => users.filter(u => u.name !== user.name));
          resolve();
        }, 10);
      });
    }
;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...