2

I've created a reducer function using Reat's useReducer hook.

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();
    }
}

And inside a component-

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

Now, I am dispatching an action after loading an API data like-

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

Now is there any way to check if the action {type: 'increment'} is fired/dispatched like how we check using the redux DevTool?

Sajeeb Ahamed
  • 6,070
  • 2
  • 21
  • 30
  • If you have the dev-tools installed then you can see the list of actions getting dispatched. Do you have the extension installed ? – Shyam Aug 30 '21 at 11:06

2 Answers2

3

You can use reinspect, if you only want to use it during development then override the webpack resolve using rescripts

To do this you need to add the dependencies:

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

Add a file called .rescriptsrc.js to the root of your project with the following content:

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

Then add a file called .webpack.js to the root of your project with the following content:

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;
};

The dev/useReducer is:

export { useReducer as default } from "reinspect";

The prod/useReducer is:

export { useReducer as default } from "react";

In your component(s) you can do the following:

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

The reason you need a dev and production component is because in production you don't want StateInspector, your root component should look something like this for development:

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

And like this for production:

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

Do not put StateInspector inside React.StrictMode because there seems to be a bug

HMR
  • 37,593
  • 24
  • 91
  • 160
2

Just create your own logging function.

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>
  );
}

Edit new-moon-0g3zd

ksav
  • 20,015
  • 6
  • 46
  • 66