过滤redux状态时得到错误消息



当我试图过滤从API提取的数据结果时,我得到了一个错误。

当我使用我的searchBar组件过滤redux数据时,当我输入任何东西时,错误消息出现。

下面是错误信息:

"错误:[Immer]一个Immer生产者返回了一个新值修改了它的草案。返回一个新值修改草稿。">

我必须做什么来过滤数据并返回新数据?

下面是我正在使用的组件和Redux TK切片。

<<p>Home.js组件/strong>
import React, {useState, useEffect} from 'react';
import { Col, Container, Row } from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import { getCountries } from '../redux/search';
// import LazyLoading from 'react-list-lazy-load';
// import { updateText } from '../redux/searchTerm';

import SearchBar from '../components/SearchBar';
import CardComponent from '../components/Card';
import DropdownMenu from '../components/DropdownMenu';

const Home = () => {
const dispatch = useDispatch();
// const [ countries, setCountries ] = useState(null);
const countries = useSelector((state) => state.search);

// const filterCountry = (searchCountry) => {
//     countries.list.payload.filter(country => country.name.toLowerCase() == searchCountry.toLowerCase())
// }
useEffect(() => {
dispatch(getCountries());
console.log(countries);
}, [dispatch]);

// console.log(countries.filter(country => country.region.toLowerCase() === 'africa'))
return (
<>
<Container className="home-container">
<Row>
<Col sm={12} md={6} className="left">
<SearchBar />
</Col>
<Col sm={12} md={6} className="right">
<DropdownMenu/>
</Col>
</Row>
<Row className="countryRow">
{ countries.status == 'success' 
?<>
{countries.list.map((country) => {
return <CardComponent key={country.name} 
title={country.name} 
image={country.flags[0]}
population={country.population} 
region={country.region} 
capital={country.capital}/>
})}
</> 
:<div>Loading.....</div>
}
</Row>
</Container>
</>
)
}
export default Home;

SearchBar.js

import React from 'react';
import {useSelector, useDispatch} from 'react-redux';
// import { updateText } from '../redux/searchTerm';
import { searchTerm } from '../redux/search';

const SearchBar = () => {
const query = useSelector((state) => state.searchDefault);
const dispatch = useDispatch();
return (
<>
<form>
<input 
className="search" 
type="search" 
placeholder="Search for a country" 
value={query}
onChange={(e) => dispatch(searchTerm(e.target.value))}/>
</form>
</>
)
}
export default SearchBar;

search.js片

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

export const getCountries = createAsyncThunk(
'searchDefault/getCountries', async () => {
try {
const resp = await axios.get('https://restcountries.com/v2/all');
return await resp.data;
} catch (error) {
console.log(error.message);
}
}
)
const searchSlice = createSlice({
name: 'searchDefault',
initialState: {
list: [],
status: null,
value: ''
},
reducers: {
searchTerm: (state, action) => {
// console.log(state.value);
state.value = action.payload
// console.log(state.value);
state.list.filter( country => country.name == state.value);
return state.list;
// console.log(state.list);

}
},
extraReducers: {
[getCountries.pending]: (state, action) => {
state.status = 'loading'
},
[getCountries.fulfilled]: (state, payload) => {
console.log(payload)
state.list = payload.payload
state.status = 'success'
},
[getCountries.rejected]: (state, action) => {
state.status = 'failed'
}
}
})
export const { searchTerm } = searchSlice.actions;
export default searchSlice.reducer;

根据redux-toolkit的文档:

Redux Toolkit的createReducer API在内部自动使用Immer。因此,"变异"已经是安全的了传递给createReducer的任何case reducer函数内部的状态:

And Immer docs:

还允许从生产者函数返回任意其他数据。但前提是你没有修改草稿

在您的减速器中,您使用immer API来改变值(state.value = action.payload)并返回结果。但是Immer只允许你做两件事中的一件,不能同时做。所以要么你改变状态

searchTerm: (state, action) => {  
state.value = action.payload; // notify redux that only the value property is dirty
}

或者完全替换新状态:

searchTerm: (state, action) => {  
return { ...state, value: action.payload }; // replace the whole state
// useful when you need to reset all state to the default value
}

大多数情况下,您只需要告诉redux片的特定属性被更改,然后redux将只通知订阅该属性的组件(通过useSelector)重新呈现。因此,删除您的reducer中的返回语句,您的代码应该可以再次工作:

searchTerm: (state, action) => {  
state.value = action.payload;
state.list = state.list.filter( country => country.name == state.value);
// remove the return statement
}

相关内容

  • 没有找到相关文章

最新更新