React: how to load redux-toolkit fully in browser (no npm)

325 views Asked by At

I’m trying to load react-toolkit + JSX fully in my browser (I don’t want any npm-based setup to keep complexity low, and, importantly, to deploy the whole website via a single html file). However, I keep getting errors about some functions being undefined, so I guess my import is failing somehow. Do you know what I’m doing wrong?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Your App</title>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/@reduxjs/[email protected]/dist/redux-toolkit.umd.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <script type="text/babel">
      const { useState } = React;
      const { configureStore, createSlice, useDispatch, useSelector, Provider } = RTK;

      const counterSlice = createSlice({
        name: 'counter',
        initialState: 0,
        reducers: {
          increment: (state) => state + 1,
          decrement: (state) => state - 1
        }
      });

      const store = configureStore({
        reducer: counterSlice.reducer
      });

      // React component using JSX
      function Counter() {
        const counter = useSelector((state) => state);
        const dispatch = useDispatch();

        return (
          <div>
            <h1>Counter: {counter}</h1>
            <button onClick={() => dispatch(counterSlice.actions.increment())}>
              Increment
            </button>
            <button onClick={() => dispatch(counterSlice.actions.decrement())}>
              Decrement
            </button>
          </div>
        );
      }

      const container = document.getElementById('root');
      const root = ReactDOM.createRoot(container);
      root.render(
        <Provider store={store}>
          <Counter />
        </Provider>
      )
    </script>
  </body>
</html>

1

There are 1 answers

3
Drew Reese On BEST ANSWER

The Provider component and the useDispatch and useSelector hooks are react-redux exports. redux-toolkit doesn't provide these.

Add <script src="https://unpkg.com/[email protected]/dist/react-redux.min.js"></script> to the app scripts and access Provider, useDispatch, and useSelector from ReactRedux.

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
    <meta charset="UTF-8" />

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

    <!-- Add this dependency -->
    <script src="https://unpkg.com/[email protected]/dist/react-redux.min.js"></script>

    <script src="https://unpkg.com/@reduxjs/[email protected]/dist/redux-toolkit.umd.js"></script>
  </head>

  <body>
    <div id="root"></div>

    <script type="text/babel">
      const { useState } = React;

      // Destructure from ReactRedux
      const { useDispatch, useSelector, Provider } = ReactRedux;
      const { configureStore, createSlice } = RTK;

      const counterSlice = createSlice({
        name: "counter",
        initialState: 0,
        reducers: {
          increment: (state) => state + 1,
          decrement: (state) => state - 1
        }
      });

      const store = configureStore({
        reducer: counterSlice.reducer
      });

      // React component using JSX
      function Counter() {
        const counter = useSelector((state) => state);
        const dispatch = useDispatch();

        return (
          <div>
            <h1>Counter: {counter}</h1>
            <button onClick={() => dispatch(counterSlice.actions.increment())}>
              Increment
            </button>
            <button onClick={() => dispatch(counterSlice.actions.decrement())}>
              Decrement
            </button>
          </div>
        );
      }

      const container = document.getElementById("root");
      const root = ReactDOM.createRoot(container);
      root.render(
        <Provider store={store}>
          <Counter />
        </Provider>
      );
    </script>
  </body>
</html>

Edit react-how-to-load-redux-toolkit-fully-in-browser-no-npm