Javascript TypeError:searchField.toLowerCase在使用redux时不是函数
为了更好地理解react,我一直在做一个小项目。我最近将它转换为使用钩子,并尝试用它实现redux。但是我现在得到了以下错误Javascript TypeError:searchField.toLowerCase在使用redux时不是函数,javascript,reactjs,redux,react-hooks,Javascript,Reactjs,Redux,React Hooks,为了更好地理解react,我一直在做一个小项目。我最近将它转换为使用钩子,并尝试用它实现redux。但是我现在得到了以下错误 TypeError: searchField.toLowerCase is not a function 查看文档时,我从react redux停止使用connect,转而使用useDispatch和useSelector。但我相信我已经正确地设置了一切,但不确定为什么会出现这个错误 这是我的action.js import { SEARCH_EVENT } from
TypeError: searchField.toLowerCase is not a function
查看文档时,我从react redux
停止使用connect
,转而使用useDispatch
和useSelector
。但我相信我已经正确地设置了一切,但不确定为什么会出现这个错误
这是我的action.js
import { SEARCH_EVENT } from './searchfield_constants';
export const setSearchField = (payload) => ({ type: SEARCH_EVENT, payload });
这是我的减速机
import { SEARCH_EVENT } from './searchfield_constants';
const initialState = {
searchField: '',
};
export const searchRobots = (state = initialState, action = {}) => {
switch (action.type) {
case SEARCH_EVENT:
return { ...state, searchField: action.payload };
default:
return state;
}
};
这是我的index.js,我使用的是提供者fromreact redux
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { searchRobots } from './searchfield/searchfield_reducers';
import './styles/index.css';
import App from './App';
const store = createStore(searchRobots);
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
从“React”导入React;
从“react dom”导入react dom;
从'react redux'导入{Provider};
从“redux”导入{createStore};
从“./searchfield/searchfield_reducers”导入{searchRobots};
导入“./styles/index.css”;
从“./App”导入应用程序;
const store=createStore(searchRobots);
ReactDOM.render(
,
document.getElementById('root'))
);
最后是我的App.jsx
import { useState, useEffect, useCallback } from 'react';
import { setSearchField } from './searchfield/searchfield_actions';
import { useDispatch, useSelector } from 'react-redux';
import axios from 'axios';
import React from 'react';
import CardList from './components/CardList';
import SearchBox from './components/SearchBox';
import Scroll from './components/Scroll';
import Error from './components/Error';
import 'tachyons';
import './styles/App.css';
// const mapStateToProps = (state) => ({
// searchField: state.searchField,
// });
// const mapDispatchToProps = (dispatch) => ({
// onSearchChange: (e) => dispatch(setSearchField(e.target.value)),
// });
const App = () => {
const searchField = useSelector(state => state.searchField)
const dispatch = useDispatch();
const [robots, setRobots] = useState([]);
// const [searchField, setSearchField] = useState('');
const fetchUsers = useCallback(async () => {
try {
const result = await axios('//jsonplaceholder.typicode.com/users');
setRobots(result.data);
} catch (error) {
console.log(error);
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
fetchUsers();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const filteredRobots = robots.filter((robot) => {
return robot.name.toLowerCase().includes(searchField.toLowerCase());
});
return !robots.length ? (
<h1 className='f1 tc'>Loading...</h1>
) : (
<div className='App tc'>
<h1 className='f1'>RoboFriends</h1>
<SearchBox searchChange={dispatch(setSearchField(e => e.target.value))} />
<Scroll>
<Error>
<CardList robots={filteredRobots} />
</Error>
</Scroll>
</div>
);
};
export default App;
从'react'导入{useState,useffect,useCallback};
从“/searchfield/searchfield_actions”导入{setSearchField};
从'react redux'导入{useDispatch,useSelector};
从“axios”导入axios;
从“React”导入React;
从“./components/CardList”导入卡片列表;
从“./components/SearchBox”导入SearchBox;
从“./components/Scroll”导入滚动;
从“./components/Error”导入错误;
输入‘超光速子’;
导入“./styles/App.css”;
//常量mapStateToProps=(状态)=>({
//searchField:state.searchField,
// });
//const mapDispatchToProps=(调度)=>({
//onSearchChange:(e)=>调度(设置搜索字段(e.target.value)),
// });
常量应用=()=>{
const searchField=useSelector(state=>state.searchField)
const dispatch=usedpatch();
const[robots,setRobots]=useState([]);
//常量[searchField,setSearchField]=useState(“”);
const fetchUsers=useCallback(异步()=>{
试一试{
const result=await axios('//jsonplaceholder.typicode.com/users');
setRobots(result.data);
}捕获(错误){
console.log(错误);
}
},[]);//eslint禁用行反应挂钩/deps
useffect(()=>{
fetchUsers();
},[]);//eslint禁用行反应挂钩/deps
常量过滤器机器人=机器人。过滤器((机器人)=>{
return robot.name.toLowerCase().includes(searchField.toLowerCase());
});
返回!机器人。长度(
加载。。。
) : (
机器人
e、 target.value)}/>
);
};
导出默认应用程序;
我做错了什么?在你的App.js中,转换这一行
const searchField = useSelector(state => state.searchField)
到
基本上从state.searchField
这归因于redux如何设置状态
在reducersearchRobots
中,redux提供的初始状态为
state = {
...state,
searchField
}
在这一行中返回{…state,searchField:action.payload}代码>,您正在添加
另一个属性searchField
设置为状态。searchField
对象,因此您需要对其进行解构。看起来您的searchField
值被设置为未定义或某些非字符串值
我发现这行不正确
<SearchBox searchChange={dispatch(setSearchField(e => e.target.value))} />
e.target.value))}/>
应该改成
<SearchBox searchChange={() => dispatch(setSearchField(e => e.target.value))} />
dispatch(setSearchField(e=>e.target.value))}/>
以便在搜索更改时可以调用此函数。当前您正在直接调用dispatch,这可能会将您的搜索字段设置为未定义
同样为了安全起见,在使用toLowerCase()
之前,将其转换为字符串iesearchField.toString().toLowerCase()
,因此解决方案如下:
我创建了一个名为searchChange的函数,它调用dispatch,然后调用setSearchField,它使用e.target.value作为有效负载
const onSearchChange = (e) => {
dispatch(setSearchField(e.target.value));
};
因此,最终返回结果如下所示
return !robots.length ? (
<h1 className='f1 tc'>Loading...</h1>
) : (
<div className='App tc'>
<h1 className='f1'>RoboFriends</h1>
<SearchBox searchChange={onSearchChange} />
<Scroll>
<Error>
<CardList robots={filteredRobots} />
</Error>
</Scroll>
</div>
);
};
返回!机器人。长度?(
加载。。。
) : (
机器人
);
};
return !robots.length ? (
<h1 className='f1 tc'>Loading...</h1>
) : (
<div className='App tc'>
<h1 className='f1'>RoboFriends</h1>
<SearchBox searchChange={onSearchChange} />
<Scroll>
<Error>
<CardList robots={filteredRobots} />
</Error>
</Scroll>
</div>
);
};