React:修复缺少依赖警告 useEffect with Refs

React: Fix missing dependency warning useEffect with Refs

我有一个功能组件,如果我在调用 API 时遇到错误,我想打开一个显示该错误的模式。使用上下文 API 存储决定此模式是否打开的 属性。 所以我在组件中有这段代码:

  const modalContext = useContext(ModalContext);

  useEffect(() => {
    if (error !== "") {
      modalContext.showModal();
    }
  }, [error]);

但是我有这个警告:

React Hook useEffect has a missing dependency: 'modalContext'. Either include it or remove the dependency array react-hooks/exhaustive-deps

我读到可以使用 refs 来解决这个问题,所以我更改了代码,现在我有:

  const modalContextRef = React.useRef(false);
  modalContextRef.current = useContext(ModalContext);

  useEffect(() => {
    if (error !== "") {
      modalContextRef.current.showModal();
    }
  }, [error]);

我想知道这是继续进行的正确方法还是不好的做法。

谢谢!

您可以尝试将modalContext添加到它的依赖中。

useEffect(() => {
  if (error !== "") {
    modalContext.showModal();
  }
}, [error, modalContext]);

也许以下内容对您有用:

const ModalContext = React.createContext();
const ModalProvider = ({ children }) => {
  const [isModalOpen, setIsModalOpen] = React.useState(
    false
  );
  //show modal never changes because using useCallback
  const showModal = React.useCallback(
    () => setIsModalOpen(true),
    []
  );
  return (
    <ModalContext.Provider
      value={{
        isModalOpen,
        showModal,
      }}
    >
      {children}
    </ModalContext.Provider>
  );
};
const Modal = () => {
  const { isModalOpen } = React.useContext(ModalContext);
  return isModalOpen ? 'modal shows' : null;
};
const App = () => {
  const [error, setError] = React.useState('');
  const { showModal } = React.useContext(ModalContext);

  React.useEffect(() => {
    if (error !== '') {
      showModal();
    }
  }, [error, showModal]);
  return (
    <div>
      <button onClick={() => setError('error')}>
        set error
      </button>
      <Modal />
    </div>
  );
};

ReactDOM.render(
  <ModalProvider>
    <App />
  </ModalProvider>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>