Создание основанного на перехватах setState с обратным вызовом - PullRequest
0 голосов
/ 14 февраля 2020

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

Вроде как это произошло:

this.setState({a: 1}, () => { 
   console.log("Ok.");
});

Я хотел бы узнать ваше мнение об этом, что вы думаете?

Могут ли быть проблемы?

Можно ли его улучшить?

Ссылка: codesandbox

Приложение:

import React from "react";
import { useStateCallback } from "./useStateCallback";

export default function App() {
  const [stateString, setStateString] = useStateCallback("James");
  const [stateObj, setStateObj] = useStateCallback({
    name: "James",
    surname: "Bond",
    number: 7
  });

  const { name, surname, number } = stateObj;

  React.useEffect(() => {
    setStateString("Bond");
    setStateString("Arthur", res => {
      console.log("State:", res);
    });
    setStateObj({
      ...stateObj,
      number: 1
    });
    setStateObj(
      {
        ...stateObj,
        name: "Arthur",
        surname: "Conan",
        number: 21
      },
      res => {
        console.log("State:", res);
      }
    );
  }, []);

  return (
    <div>
      State: {stateString}
      <br />
      <br />
      Name: {name}
      <br />
      Surname: {surname}
      <br />
      Number: {number}
      <br />
    </div>
  );
}

useStateCallback:

import { useState } from "react";
const useStateCallback = initialState => {
  const [state, setState] = useState(initialState);
  return [
    state,
    (state, callback) => {
      setState(state);
      return callback && callback(state);
    }
  ];
};
export { useStateCallback };

1 Ответ

0 голосов
/ 14 февраля 2020

В этой реализации я вижу две проблемы:

  1. Вам необходимо проверить, является ли callback функцией, или вы открываете комнату для ошибки времени выполнения:
setStateString('Arthur', { hello: 'hello' });
При каждом рендеринге пользовательский хук возвращает новый экземпляр функции установщика, что не является ожидаемым поведением, которое может привести к повторному запуску useEffect s:
export default function App() {
  const [stateString, setStateString] = useStateCallback('James');
  const [, setCounter] = useState(0);

  React.useEffect(() => {
    setStateString('Arthur', res => {
      console.log('State:', res);
    });
  }, [setStateString]);

  return (
    <div>
      State: {stateString}
      <button onClick={() => setCounter(p => p + 1)}>Render</button>
    </div>
  );
}

Чтобы устранить эти проблемы, проверьте тип callback и запомните установщик:

export const useStateCallback = initialState => {
  const [state, setState] = useState(initialState);
  const setter = useCallback((state, callback) => {
    setState(state);
    return typeof callback === 'function' && callback(state);
  }, []);
  return [state, setter];
};

Edit Q-60226754-useStateCallbackFix

Примечание: вы можете заметить что этот хук именно то, что делает useEffect.

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