【问题标题】:Show react reducer actions like redux devTool显示 react reducer 操作,例如 redux devTool
【发布时间】:2021-08-30 10:31:29
【问题描述】:

我使用 Reat 的 useReducer 钩子创建了一个 reducer 函数。

function reducer(state, action) {
    switch (action.type) {
        case 'increment':
            return { count: state.count + action.payload };
        case 'decrement':
            return { count: state.count - action.payload };
        default:
            throw new Error();
    }
}

在组件内部-

const [state, dispatch] = useReducer(reducer, {count: 0});

现在,我在加载 API 数据后调度一个动作,例如 -

useEffect(() => {
  (async () => {
    const res = await fetch(some_url);
    const data = await res.json();
    dispatch({type: 'increment', payload: data});
  )();
})

现在有什么方法可以像我们使用 redux DevTool 一样检查动作 {type: 'increment'} 是否被触发/调度?

【问题讨论】:

  • 如果您安装了开发工具,那么您可以看到正在调度的操作列表。你有安装扩展吗?

标签: javascript reactjs redux use-reducer


【解决方案1】:

只需创建您自己的日志记录功能。

import { useReducer, useEffect } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { count: state.count + action.payload };
    case "decrement":
      return { count: state.count - action.payload };
    default:
      throw new Error();
  }
}

const addLoggingToDispatch = (dispatch, args) => {
  console.log(args);
  dispatch(args);
};

export default function App() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  useEffect(() => {
    addLoggingToDispatch(dispatch, { type: "increment", payload: "data" });
  }, []);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

【讨论】:

    【解决方案2】:

    你可以使用reinspect,如果你只想在开发过程中使用它,那么override the webpack resolve使用rescripts

    为此,您需要添加依赖项:

    yarn add @rescripts/cli -D
    yarn add @rescripts/rescript-env -D
    yarn add reinspect -D
    

    将名为.rescriptsrc.js 的文件添加到项目的根目录,内容如下:

    module.exports = [require.resolve("./.webpack.js")];
    

    然后将名为.webpack.js 的文件添加到项目的根目录,内容如下:

    const path = require("path");
    module.exports = (config) => {
      const file =
        process.env.NODE_ENV === `development`
          ? "src/dev/useReducer.js"
          : "src/prod/useReducer.js";
      config.resolve.alias.useReducer = path.resolve(
        __dirname,
        file
      );
      //do the same with your root component (./index.js)
      return config;
    };
    

    dev/useReducer 是:

    export { useReducer as default } from "reinspect";
    

    prod/useReducer 是:

    export { useReducer as default } from "react";
    

    在您的组件中,您可以执行以下操作:

    import useReducer from "useReducer"; 
    ...
      const [state, dispatch] = useReducer(
      reducer,
      {
        count: 0,
      },
      undefined,
      "componentName"
    );
    

    您需要一个开发和生产组件的原因是因为在生产中您不需要 StateInspector,您的根组件在开发时应该看起来像这样:

    import { StateInspector } from "reinspect";
    ReactDOM.render(
      <StateInspector name="App">
        <React.StrictMode>
          <App />
        </React.StrictMode>
      </StateInspector>,
      document.getElementById("root")
    );
    

    像这样用于生产:

    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById("root")
    );
    

    不要将 StateInspector 放在 React.StrictMode 中,因为 there seems to be a bug

    【讨论】:

      猜你喜欢
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 2018-10-16
      • 1970-01-01
      • 2019-06-03
      • 2017-10-08
      • 2016-05-30
      相关资源
      最近更新 更多