1

I'm doing a simple React app where any user introduce a text in the input text, and automatedly it will update the state in the store. It is very simple practice of React but I'm getting very struggle and frustrated with this error because I tried everything but I'm still having the same problem.

I am using "react-redux" and "@reduxjs/toolkit" dependencies. I tried everything, I checked and compare similar examples and solutions to similar problems, I remade the app from the scratch just to make sure that there is not any problem with different versions of the dependencies, and I keep my code very simple trying to make it work, but it doesn't.

I hope any of you could give me an advice or solution. Thank You!!

Error

TypeError: Object(...) is not a function
handleChange
C:/Users/Ruben/Desktop/Projects/React/reddit2/reddit/src/features/search/SearchBar.js:14
  11 | 
  12 | 
  13 |  const handleChange = (e) => {
> 14 |    dispatch(setSearchTerm(e.target.value))
     | ^  15 |  }
  16 | 
  17 | 
View compiled
▶ 19 stack frames were collapsed.
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.  Click the 'X' or hit ESC to dismiss this message.

Those are the files:

SearchBar Component

import React from "react";
import {useDispatch, useSelector} from "react-redux";
import {setSearchTerm, selectSearchTerm} from "../search/searchSlice";


export const SearchBar = () => {
  
  
  const dispatch = useDispatch();
  const term = useSelector(selectSearchTerm);


  const handleChange = (e) => {
    dispatch(setSearchTerm(e.target.value))
  }


  return(
    <div>
      <input
        id="search"
        type="text"
        value={term}
        onChange={handleChange}
        placeholder="Introduce your Topic"
        />
    </div>
  );
};

searchSlice

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


export const searchSlice = createSlice({
  name: 'search',
  initialState: '',
  reducer: {
    setSearchTerm: (state, action) => {state.search = action.payload},
  }
});

export const {setSearchTerm} = searchSlice.actions;

export const selectSearchTerm = (state) => state.search;

export default searchSlice.reducer;

Store

import {configureStore} from "@reduxjs/toolkit";
import searchReducer from "../features/search/searchSlice";

export default configureStore({
  reducer: {
    search: searchReducer,
  },
});

Index

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from "react-redux";
import './index.css';
import App from '../src/App/App';
import reportWebVitals from './reportWebVitals';
import store from "../src/App/store";

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>  
  </React.StrictMode>,
  document.getElementById('root')
);

Package.json

{
  "name": "reddit",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@reduxjs/toolkit": "^1.5.1",
    "@testing-library/jest-dom": "^5.13.0",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.4",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.1.2"
  },
6
  • 1
    There are multiple things to debug. onChange={(e)=>handleChange(e.target.value)} , const handleChange = (value) => { dispatch(setSearchTerm(value)) } . Read about synthetic events. Can you add code for setSearchTerms? Commented Jun 4, 2021 at 18:20
  • Thank you for your comment Anglesvar, but still the same problem. setSearchTerm is the action creator of the searchSlice reducer, the file is posted. Commented Jun 4, 2021 at 18:38
  • setSearchTerm is actually taking two parameters according to your code. (state, action) . So this is the reason the error is thrown. I would suggest you to look into action, reducer, store concept thoroughly. Hope it help! Commented Jun 4, 2021 at 18:48
  • 1
    @Anglesvar setSearchTerm is the name of the reducer function in the slice, which does take the normal state and action arguments, however redux-toolkit builds action creator functions for export (i.e. searchSlice.actions), which take only a single argument (i.e. payload) by default. Commented Jun 4, 2021 at 18:59
  • Thank you Anglesvar, but I had a second look, and it looks right the code, I don't know what I'm missing. Thank you @DrewReese for your comment as well. Commented Jun 4, 2021 at 19:09

1 Answer 1

1

Issues

  1. You've a typo in the createSlice, the proper key is reducers, with an "s", not reducer. This is causing the slice actions to actually be undefined.
  2. Your state isn't quite correct. It's not a draftable object.

Solution

Correct the reducer key and provide correct state.

export const searchSlice = createSlice({
  name: "search",
  initialState: { search: "" }, // <-- object state
  reducers: {
    setSearchTerm: (state, action) => {
      state.search = action.payload; // <-- update property
    }
  }
});

export const { setSearchTerm } = searchSlice.actions;

export const selectSearchTerm = (state) => state.search.search; // <-- select property

export default searchSlice.reducer;

Edit react-usedispatch-typeerror-object-is-not-a-function-handlechange

Sign up to request clarification or add additional context in comments.

1 Comment

Thank You very much, Drew Reese, finally after the whole day trying, changing, looking...., you fixed my problem, thank you very much not only for fixing my problem, I wasn't sure about the initial state has to be an object, and I never will forget to put an 's' again in reducers........:P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.