【问题标题】:(React) useDispatch TypeError: Object(...) is not a function handleChange(React) useDispatch TypeError: Object(...) is not a function handleChange
【发布时间】:2021-08-22 18:39:53
【问题描述】:

我正在做一个简单的 React 应用程序,任何用户在输入文本中引入一个文本,它会自动更新商店中的状态。 这是非常简单的 React 实践,但我对这个错误感到非常挣扎和沮丧,因为我尝试了所有方法,但仍然遇到同样的问题。

我正在使用“react-redux”和“@reduxjs/toolkit”依赖项。我尝试了一切,我检查并比较了类似问题的类似示例和解决方案,我从头开始重新制作应用程序,以确保不同版本的依赖项没有任何问题,并且我保持我的代码非常简单它工作,但它没有。

我希望你们中的任何人都可以给我一个建议或解决方案。 谢谢!!

错误

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.

这些是文件:

搜索栏组件

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

搜索切片

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;

商店

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

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

索引

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"
  },

【问题讨论】:

  • 要调试的东西有很多。 onChange={(e)=&gt;handleChange(e.target.value)}const handleChange = (value) =&gt; { dispatch(setSearchTerm(value)) }。阅读合成事件。可以为 setSearchTerms 添加代码吗?
  • 感谢您对 Anglesvar 的评论,但仍然是同样的问题。 setSearchTerm 是 searchSlice reducer 的 action creator,文件贴出来。
  • setSearchTerm 实际上是根据您的代码采用两个参数。 (state, action) 。所以这就是引发错误的原因。我建议您彻底研究行动,减速器,存储概念。希望对您有所帮助!
  • @Anglesvar setSearchTerm 是切片中 reducer 函数的名称,确实采用普通的 stateaction 参数,然而 redux-toolkit 构建了用于导出的动作创建函数(即searchSlice.actions),默认情况下它只接受一个参数(即payload)。
  • 谢谢Anglesvar,但我又看了一遍,代码看起来正确,我不知道我错过了什么。也感谢@DrewReese 的评论。

标签: reactjs redux react-redux typeerror redux-toolkit


【解决方案1】:

问题

  1. 您在createSlice 中有错字,正确的键是reducers,带有“s”,而不是reducer。这导致切片操作实际上是未定义的。
  2. 您的状态不太正确。它不是一个可绘制的对象。

解决方案

更正reducer key并提供正确的状态。

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;

【讨论】:

  • 非常感谢你,Drew Reese,终于经过一整天的尝试、改变、寻找......,你解决了我的问题,非常感谢你不仅解决了我的问题,我还没有不确定初始状态必须是一个对象,而且我永远不会忘记在减速器中再次放置一个's'......:P
  • @RubenGonzalez 欢迎您!如果此答案解决了您的问题/问题,那么我邀请您将其标记为已接受的答案。不要忘记也为您在 SO 上找到的有用和有用的问题、cmets 和答案投票。干杯,祝你好运。
  • 谢谢你,德鲁里斯。我是新来的,我不知道您对标记已接受的答案和赞成票是什么意思。我终于找到了,但不幸的是,它不允许我对解决方案进行投票,因为我的声誉不到 15,但我保证,当我达到这个数字时,我会这样做。
猜你喜欢
  • 1970-01-01
  • 2019-04-05
  • 2021-10-26
  • 2020-03-01
  • 2018-05-02
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
  • 2018-11-16
相关资源
最近更新 更多