#reactjs #redux #react-hooks #reducers
#reactjs #redux #реагирующие хуки #редукторы
Вопрос:
У меня есть компонент с именем Restaurante
, в котором я пытаюсь вызвать действие FETCH_ALL
из моего ресторанного редуктора. Я успешно использую эту информацию из MongoDB.
Чтобы получить эту информацию, я использую хук useEffect, где я вызываю действие getRestaurantes()
useEffect(() => {
dispatch(getRestaurantes());
}, [ currentId, dispatch ]);
У меня есть еще один вызываемый компонент RestauranteData
, который представляет собой таблицу, в которой отображается вся информация, полученная с помощью dispatch
и useSelector
перехвата
const dispatch = useDispatch();
const restaurantes = useSelector((state) => state.restaurantes);
Как вы можете видеть, информация успешно отображается в таблице:
Мне нужно вызвать другое действие, чтобы получить информацию из другой вызываемой коллекции consecutitvos
. В этой коллекции есть информация, которая позволила бы мне создать пользовательский идентификатор, когда пользователь создает новый ресторан. Чтобы получить эту информацию, у меня есть вызываемое действие 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 ]);
Полный код RestauranteData (рендеринг таблицы)
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 reducer code
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')
);
Комментарии:
1. Состояние перезаписано …? Пожалуйста, укажите в своем вопросе соответствующий код редуктора, который обрабатывает эти отправленные действия и состояние обновления. Может помочь также включить более полный пример кода компонента, отображающий таблицу.
2. если вы добавляете состояние по умолчанию в свою функцию редуктора, проверьте свою функцию переключения, существует ли состояние по умолчанию или нет
3. имя типа действия одинаково в обеих функциях редуктора, я думаю, что это была проблема
4. кажется, что restaurantes и consecutivos используют один и тот же тип, используйте ‘CREATE@RESTAURANTE’, ‘CREATE@CONSECURTIVO’ вместо использования CREATE в обоих create
5. У Баскарана это есть. Вы используете одни и те же типы действий в двух разных редукторах, это запускает обработку полезной нагрузки в «другом» редукторе, когда вы этого не хотите.
Ответ №1:
В вашей функции редуктора вы будете использовать разные имена типов действий вместо использования одних и тех же имен, а также изменять имена типов действий в ваших методах действий
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;
Комментарии:
1. Я внес изменения, как вы предложили, и теперь он запущен и работает! Спасибо за помощь и за то, что нашли время ответить на мой вопрос!