I have a problem with applying redux-toolkit to my project

I am doing a simple project which contains a local server 5000 ,where I post a new user with name / age, and redux-toolkit where I created userSlice, store, and a small form. when I am trying to post a new user and get response the error is >>>>

(0 , _redux_userSlice__WEBPACK_IMPORTED_MODULE_0__.startUser) is not a function
TypeError: (0 , _redux_userSlice__WEBPACK_IMPORTED_MODULE_0__.startUser) is not a function
    at postUser (http://localhost:3000/static/js/bundle.js:102:71)
    at handleSubmit (http://localhost:3000/static/js/bundle.js:193:58)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:13786:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:13830:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:13887:35)
    at invokeGuardedCallbackAndCatchFirstError (http://localhost:3000/static/js/bundle.js:13901:29)
    at executeDispatch (http://localhost:3000/static/js/bundle.js:18045:7)
    at processDispatchQueueItemsInOrder (http://localhost:3000/static/js/bundle.js:18071:11)
    at processDispatchQueue (http://localhost:3000/static/js/bundle.js:18082:9)
    at dispatchEventsForPlugins (http://localhost:3000/static/js/bundle.js:18091:7)

here are my files :
1- api.js

import axios from "axios";
import  { startUser, successUser, errorUser } from "../redux/userSlice";

export const postUser = async (user, dispatch) => {
    dispatch(startUser());

    try{
        const response = await axios.post("http//localhost:5000/api/users", user);
        dispatch(successUser(response.data));
    }catch(error){
        dispatch(errorUser());
    }

}

2- userSlice.js

import { createSlice } from "@reduxjs/toolkit";

export const userSlice = createSlice({
  name: "user",

  initialState : {
    userData: {
      name: "",
      age: "",
    },
    loading: null,
    error: null,
  },

  reducer: {
    addUser: (state, action) => {
      state.userData.name = action.payload.name;
    },

    addAge: (state, action) => {
      state.userData.age = action.payload.age;
    },

    startUser: (state) => {
      state.loading = true;
    },

    successUser: (state, action) => {
      state.userData = action.payload;
      state.loading = false;
    },

    errorUser: (state) => {
      state.loading = false;
      state.error = false;
    },
  },
});

export const { addUser, addAge, startUser, successUser, errorUser } =
  userSlice.actions;
export default userSlice.reducer;

3.Form.js

import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
// import {
//   addUser,
//   addAge,
//   startUser,
//   successUser,
//   errorUser,
// } from "../redux/userSlice";
import { postUser } from "../api/api.js";

const Form = () => {
  const [name, setName] = useState("");
  const [age, setAge] = useState("");
  const dispatch = useDispatch();

  const { userData, error, loading } = useSelector((state) => state.user);
  console.log(userData, error, loading);

  const handleSubmit = (e) => {
    e.preventDefault();
    // this method will update userSlice without api:
    // dispatch(addUser({name, age}));
    // this method will update api and api will update userSlice:
    // console.log(`${name} & ${age}`);
    postUser({ userData, error, loading }, dispatch);
    // dispatch(addUser({name, age}));
  };

  return (
    <div>
      <form  onSubmit={handleSubmit}>
        <div>
          <input type="text" onChange={(e) => setName(e.target.value)} value={name}  placeholder="enter name"/>
        </div>
        <div>
          <input type="number" onChange={(e) => setAge(e.target.value)} value={age} placeholder="enter age" />
        </div>

        {loading ? (
          "Loading ..........."
        ) : (
          <div>
            <button> Add User </button>
          </div>
        )}

        {error && loading === "false" && <span> Something Went Wrong !!!</span>}
      </form>
    </div>
  );
};

export default Form;

  1. Header.js
import React from "react";
import { useSelector } from "react-redux";

const Header = () => {
  const { userData } = useSelector((state) => (state.user));
  // console.log(userData);
  // you can destructure the userData like this :
  // const {name} = useSelector((state) => state.user.userData);

  return (
    <div>
      <p> Hello {userData.name} </p>
      <p> Your age is {userData.age} </p>
    </div>
  );
};

export default Header;

  1. store.js
import { configureStore } from "@reduxjs/toolkit";
import userSlice from "./userSlice";

const store = configureStore({
  reducer: {
    user: userSlice,
  },
});

export default store;

and finally my server as server.js :

const express = require("express");
const cors = require("cors");

const app = express();

app.use(cors());
app.use(express.json());


app.post("api/users", (request,response) => {
	setTimeout(function() {
		response.send(request.body)
	}, 2000)
});


app.listen("5000", () => {
	console.log("server is running on port 5000");
});

Thanks in advance.

createSlice takes an object with a reducers property, not reducer

Ok, thanks, it partially works :smile: but I’ve got another error :smile:

Well, that URL doesn’t make any sense.

Are you using create-react-app with a proxy set in the package-json?


Please post a GitHub repo with all your code so people can better help you.

No, I am not using proxies.
Here are my package.json for react-app:

{
  "name": "redux-small-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@reduxjs/toolkit": "^1.9.5",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.4.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-redux": "^8.0.7",
    "react-scripts": "5.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

and package.json for server(5000):

{
  "name": "express_server",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.18.2",
    "nodemon": "^2.0.22"
  }
}

server_3000

server_5000

This is the link to my repo for this project :slight_smile:

redux-toolkit-crud-ops

You are missing a colon : in the Axios POST URL http://

You should use /api/users on the backend (/route/path).

1 Like

Thank you Lasjorg for helping me out, but it did not work.
Now, I have modified server.js as follows:

const express = require("express");
const cors = require("cors");

const app = express();

app.use(cors());
app.use(express.json());


app.post("/api/users", (request,response) => {
	setTimeout(function() {
		response.send(request.body)
	}, 2000)
});


app.listen("5000", () => {
	console.log("server is running on port 5000");
});

and also modified api.js as follows:

import axios from "axios";
import  { startUser, successUser, errorUser } from "../redux/userSlice";

export const postUser = async (user, dispatch) => {
    dispatch(startUser());

    try{
        const response = await axios.post("http://localhost:5000/api/users", user);
        dispatch(successUser(response.data));
    }catch(error){
        dispatch(errorUser());
    }

}

Do you have any idea what’s going on ?.
Thanks in advance

Also, I would like to show me how to debug and resolve as you did previously (reducers issue, http: issue, … ) . I spent so many hours trying to figure it out, but I didn’t get a clue.
Thanks again :slight_smile:

I mean it did work because you are not getting the same error.

Did you restart the server after changing the route?


For the reducer I just looked at the docs as I don’t really use Redux Toolkit much. For the HTTP I just looked at the POST URL again and saw it.

Catching errors like that is more about pattern recognition. Just like how you might catch a typo. You get used to it over time, it isn’t really about programming as much as it is about pattern recognition. Sort of like the “find five errors” game if you know that one.

1 Like

I filled up the inputs and submitted, but the state returned empty.

Yes I know this game and I got your point.

Dear lasjorg, I still can’t find out what’s wrong with my code, but I did not get the expected output, would you please take a closer look, maybe I miss something or miss configure something.
Thanks

Please push your latest code the repo still has the old code with the errors I already mentioned.


You do not seem to be using the form data for anything.

If you dispatch response.data then the request.body on the server is an object with the userData property on it. You likely want to dispatch response.data.userData. Or if you keep it as is, send request.body.userData instead.

1 Like

Thank you so much lasjorg. My greetings for you :slight_smile:

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.