Реагировать: обратный вызов в EventListener получить старое состояние - PullRequest
0 голосов
/ 21 февраля 2020

Я создаю компонент, который добавляет обработчик событий на mousedown, удаляет прослушиватель на mouseup и вызывает обратный вызов родителя в handleMouseup, но если я не использую useCallback() и добавляю обратный вызов родителя для deps обратный вызов события не будет обновлен, и ссылка будет нулевой.

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

Вы можете найти мой код здесь: https://codesandbox.io/s/lucid-mountain-ick7e

const AppContext = React.createContext();
export default function App() {
  // const ref = React.useRef();
  const [ref, setRef] = React.useState(null);

  return (
    <AppContext.Provider value={{ ref }}>
      <div className="App" ref={ref => setRef(ref)}>
        <h1>Hello CodeSandbox</h1>
        <Parent />
      </div>
    </AppContext.Provider>
  );
}
function Parent(props) {
  const { ref } = React.useContext(AppContext);
  function parentCallback(e) {
    console.log(ref);
  }
  return <Child onChange={parentCallback} />;
}
function Child(props) {
  const btn = React.useRef();
  function onMouseDown(e) {
    props.onChange(e);
    btn.current.addEventListener("mouseup", onMouseUp);
  }
  // if I don't add onChange to useCllback deps,
  // parent ref in onChange cllback will be null.
  function onMouseUp(e) {
    props.onChange(e);
    btn.current.removeEventListener("mouseup", onMouseUp);
    btn.current.removeEventListener("mousedown", onMouseDown);
  }
  useEffect(() => {
    btn.current.addEventListener("mousedown", onMouseDown);
  }, []);

  return <button ref={btn}>click me</button>;
}

1 Ответ

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

То, что вы могли бы сделать, это использовать систему событий React, как предложено azium. Это будет выглядеть примерно так:

function Child({ onMouseDown, onMouseUp }) {
  const handleMouseDown = event => {
    if (onMouseDown) onMouseDown(event);
  };
  const handleMouseUp = event => {
    if (onMouseUp) onMouseUp(event);
  };

  return (
    <button onMouseDown={handleMouseDown} onMouseUp={handleMouseUp}>
      click me
    </button>
  );
}

Или как здесь: https://codesandbox.io/s/smoosh-butterfly-6m49f

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

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