【问题标题】:React state overwrites the current reducerReact 状态覆盖了当前的 reducer
【发布时间】:2021-06-10 03:50:21
【问题描述】:

我有一个名为 Restaurante 的组件,我试图从我的餐厅减速器中调用操作 FETCH_ALL。我正在从 MongoDB 成功地使用这些信息。

为了获取该信息,我使用了 useEffect 钩子,我将操作称为 getRestaurantes()

useEffect(() => {
   dispatch(getRestaurantes());
}, [ currentId, dispatch ]);

我有另一个名为RestauranteData 的组件,它是一个表格,显示使用dispatchuseSelector 挂钩获得的所有信息

const dispatch = useDispatch();
const restaurantes = useSelector((state) => state.restaurantes);

如您所见,信息已成功显示在表格中:

我需要调用另一个操作来从另一个名为 consecutitvos 的集合中获取信息。此集合包含允许我在用户创建新餐厅时创建自定义 ID 的信息。为了获得这些信息,我有一个名为 getConsecutivos 的操作。

useEffect(() => {
        dispatch(getConsecutivos());
    });

const selectedConsecutivo = useSelector((state) => !currentConsecutivo ? state.consecutivos.find((c) => c.type === "Restaurants") : null);

我遇到的问题是,当我调用该操作时,状态会覆盖,有时表格会显示consecutitvos 信息而不是餐馆的信息。如果我重新加载页面,表格中显示的信息会发生变化。

这是我在Restaurante 组件中的完整代码

const Restaurante = () => {

    const [currentId, setCurrenteId] = useState(null);
    const [show, setShow] = useState(false);
    const dispatch = useDispatch();
    const [inputSearchTerm, setinputSearchTerm] = useState('');
    const [selectedTypeSearch, setSelectedTypeSearch] = useState('');
    const [inputSearchTermError, setinputSearchTermError] = useState('');
    const [currentConsecutivo, setCurrentConsecutivo] = useState(null);

    const reload=()=>{window.location.reload()};
   
    useEffect(() => {
        dispatch(getConsecutivos());
    });

   const selectedConsecutivo = useSelector((state) => !currentConsecutivo ? state.consecutivos.find((c) => c.tipo === "Restaurantes") : null);
   console.table(selectedConsecutivo);

    

    
    
    useEffect(() => {
        dispatch(getRestaurantes());
    }, [ currentId, dispatch ]);

RestaurantData完整代码(渲染表格)

const RestauranteData = ({ setShow, currentId,  setCurrenteId, inputSearchTerm, selectedTypeSearch}) => {

    
    const dispatch = useDispatch();
    const restaurantes = useSelector((state) => state.restaurantes);

    console.log(restaurantes);

    return(
    
        <Table className="text-center" striped>
            <thead>
                <tr>
                    <th>Código</th>
                    <th>Nombre</th>
                    <th>Dirección</th>
                    <th>Cantidad de Clientes</th>
                    <th>Teléfono</th>
                    <th>Acciones</th>
                </tr>
            </thead>
            <tbody className="text-white">
                {restaurantes.filter( restaurante => {

                    if(!inputSearchTerm){
                        return restaurante;

                    }else if( selectedTypeSearch === "codigo"){

                        if(restaurante.codigo.toLowerCase().includes(inputSearchTerm.toLowerCase())){

                            console.table(restaurante);
                            return restaurante;
                        }
                    }else if( selectedTypeSearch === "nombre"){

                        console.log(restaurante.descripcion);

                        if(restaurante.nombre.toLowerCase().includes(inputSearchTerm.toLowerCase())){
                            return restaurante;
                        }
                    }
                }).map( restaurante => {
        
                    return(
                        <tr key={restaurante._id}>
                            <td key={restaurante.codigo}>{restaurante.codigo}</td>
                            <td key={restaurante.nombre}>{restaurante.nombre}</td>
                            <td key={restaurante.direccion}>{restaurante.direccion}</td>
                            <td key="2">2</td>
                            <td key={restaurante.telefono}>{restaurante.telefono}</td>
                            <td>
                                <Button variant="outline-light" className="btn-action" onClick={() => {setCurrenteId(restaurante._id); setShow(true)}} ><FontAwesomeIcon icon={faPen}></FontAwesomeIcon></Button>
                                <Button variant="outline-light" className="btn-action" onClick={() => dispatch(deleteRestaurante(restaurante._id))}><FontAwesomeIcon icon={faTrash}></FontAwesomeIcon></Button>
                            </td>
                        </tr>
                    )
                })}
            </tbody>
        </Table>
        
    );
}

export default RestauranteData; 

restaurantes.js 减速器代码

const reducer = (restaurantes = [], action) => {
    switch (action.type) {
        case 'DELETE':
            return restaurantes.filter((restaurante) => restaurante._id !== action.payload); //keep all the restaurantes but the action.payload
        case 'UPDATE':
            return restaurantes.map((restaurante) => restaurante._id === action.payload.id ? action.payload : restaurante);
        case 'FETCH_ALL':
            return action.payload;
        case 'CREATE':
            return [...restaurantes, action.payload];
    
        default:
            return restaurantes;
    }
}

export default reducer; 

consecutivos.js 减速器代码

const reducer = (consecutivos = [], action) => {
    switch (action.type) {
        case 'DELETE':
            return consecutivos.filter((consecutivo) => consecutivo._id !== action.payload); //keep all the consecutivos but the action.payload
        case 'UPDATE':
            return consecutivos.map((consecutivo) => consecutivo._id === action.payload.id ? action.payload : consecutivo);
        case 'FETCH_ALL':
            return action.payload;
        case 'CREATE':
            return [...consecutivos, action.payload];
    
        default:
            return consecutivos;
    }
}

export default reducer; 

index.js 组合减速器

import { combineReducers } from 'redux';
import consecutivos from './consecutivos';
import restaurantes from './restaurantes';


export default combineReducers({ consecutivos, restaurantes });

应用的index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'; //Keep track of the Store
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers';

import App from './App';

const store = createStore(reducers, compose(applyMiddleware(thunk)));


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

【问题讨论】:

  • 状态被覆盖...?请在您的问题中包含处理这些分派操作和更新状态的相关减速器代码。还包括一个更全面的组件代码示例来呈现表格可能会有所帮助。
  • 如果你在 reducer 函数中添加了默认状态,检查你的 switch 函数是否存在默认状态
  • 两个reducer函数中的动作类型名称相同我认为这是问题
  • 似乎餐厅和 consecutivos 使用相同的类型,请使用 'CREATE@RESTAURANTE'、'CREATE@CONSECURTIVO' 而不是在两者中都使用 CREATE
  • 巴斯卡兰有。您在两个不同的减速器中使用相同的操作类型,当您不希望它触发“其他”减速器中的有效负载处理时。

标签: reactjs redux react-hooks reducers


【解决方案1】:

在你的 reducer 函数中,你将使用不同的动作类型名称而不是使用相同的名称并在你的动作方法中更改动作类型名称

const reducer = (restaurantes = [], action) => {
    switch (action.type) {
        case 'DELETE_RESTAURANT':
            return restaurantes.filter((restaurante) => restaurante._id !== action.payload); //keep all the restaurantes but the action.payload
        case 'UPDATE_RESTAURANT':
            return restaurantes.map((restaurante) => restaurante._id === action.payload.id ? action.payload : restaurante);
        case 'FETCH_ALL_RESTAURANT':
            return action.payload;
        case 'CREATE_RESTAURANT':
            return [...restaurantes, action.payload];
    
        default:
            return restaurantes;
    }
}

export default reducer; 



const reducer = (consecutivos = [], action) => {
    switch (action.type) {
        case 'DELETE_CONSECUTIVOS':
            return consecutivos.filter((consecutivo) => consecutivo._id !== action.payload); //keep all the consecutivos but the action.payload
        case 'UPDATE_CONSECUTIVOS':
            return consecutivos.map((consecutivo) => consecutivo._id === action.payload.id ? action.payload : consecutivo);
        case 'FETCH_ALL_CONSECUTIVOS':
            return action.payload;
        case 'CREATE_CONSECUTIVOS':
            return [...consecutivos, action.payload];
    
        default:
            return consecutivos;
    }
}

export default reducer; 

【讨论】:

  • 我按照您的建议进行了更改,现在它已经启动并运行了!感谢您的帮助并花时间回答我的问题!
猜你喜欢
  • 2018-09-29
  • 1970-01-01
  • 2018-05-29
  • 2020-01-15
  • 2019-03-27
  • 2022-01-06
  • 1970-01-01
  • 2021-11-09
  • 2021-01-08
相关资源
最近更新 更多