Компонент повторного преобразования при изменении состояния в другом редукторе

#reactjs #react-redux #react-lifecycle #react-lifecycle-hooks

#reactjs #react-redux #реагировать-жизненный цикл #реагировать-жизненный цикл-хуки

Вопрос:

Хорошо, итак, я работаю над простым приложением для сбора рецептов, где у меня есть cuisineReducer.js и RecipeReducer.js . введите описание изображения здесь

и на моей панели администратора пользователю-администратору разрешено создавать, удалять и редактировать любые кулинарные группы, а также создавать, удалять и редактировать рецепты для любой кулинарной группы. когда пользователь нажимает на любую кулинарную группу, она отображает все рецепты на панели рецептов, используя идентификатор кухни. пользователь также может удалить, нажав «x» на рецепте или в группе кухни. Конфликт, который мне нужно разрешить, заключается в том, что при удалении рецепта его также следует удалить из пользовательского интерфейса без необходимости обновления. Я не знаю, как этого добиться. Вот мой код.

CuisineReducer.js

 import { GET_CUISINES, GET_CUISINE_BY_ID, GET_CUISINE_BY_CATEGORY} from "../actions/types.js"; 
const initialState = { 
      cuisines: [],
      cuisine:{}
};

export default function (state = initialState, action) { 
    switch(action.type) {
        case GET_CUISINES:
             return {
                     ...state,  
                     cuisines:action.payload
                    }; 
        case GET_CUISINE_BY_CATEGORY:
             return {
                     ...state,  
                     cuisines:action.payload
                    }; 
        case GET_CUISINE_BY_ID:
             return {
                     ...state,  
                     cuisine:action.payload
                    }; 
        default:
             return state; 
}
  

CuisineActions.js

 import {  GET_CUISINES, GET_CUISINE_BY_ID} from "./types.js"; 
import axios from 'axios'; 

export const getCuisines = () =>async dispatch => { ... }

export const getCuisineByCategory = (id) =>async dispatch => { 
     const res = await axios.get(`/api/cuisine/${id})
     dispatch({
           type:GET_CUISINES_BY_CATEGORY,
           payload: res.data
     }); 

export const getCuisineById = (id) =>async dispatch => { 
     const res = await axios.get(`/api/cuisine/${id})
     dispatch({
           type:GET_CUISINE_BY_ID,
           payload: res.data
     }); 
}
  

recipeReducer.js

 import { GET_RECIPES, GET_RECIPE_BY_ID, DELETE_RECIPE} from "../actions/types.js"; 

const initialState = { 
      recipes: [],
      recipe:{}
};

export default function (state = initialState, action) { 
    switch(action.type) {
        case GET_RECIPES:
             return {
                     ...state,  
                     recipes:action.payload
                    }; 
        case GET_RECIPE_BY_ID:
             return {
                     ...state,  
                     recipe:action.payload
                    }; 
       case DELETE_RECIPE:
             return {
                     ...state,  
                     recipes:state.recipes.filter(asset => asset.id != action.payload)
                    }; 
        default:
             return state; 
}
  

RecipeActions.js

 import { DELETE_RECIPE} from "./types.js"; 
import axios from 'axios'; 

export const getRecipes = () =>async dispatch => { ... }

export const deleteRecipe = (id) =>async dispatch => { 
     await axios.delete(`/api/recipe/${id})
     dispatch({
           type:GET_RECIPE_BY_ID,
           payload: id
     }); 
}
  

Admin.js

 import React, {Component} from react; 
import {connect} from 'react-redux'; 
import { getCuisineById, getCuisinesByCategory} from '../../actions/cuisineAction.js';
import AdminCuisineList from '../AdminCuisineList.js;
import AdminRecipeList from '../AdminRecipeList.js"; 

Class Admin extends Component {

   componentWillUnmount = () => {
       this.props.clearCuisine(); 
   }

   revealList = category => {
       this.props.getCuisinesByCategory(caegory); 
   }

   revealRecipeList = id => {
     this.props.getCuisineById(id); 
   }

 render () {
  const {cuisines} = this.props; 
  return(
   <div>
    <div>      
     <ul> 
       <li onClick={() => revealList('meal')}>  Meal </li>
       <li onClick={() => revealList('meal')}>   Deserts </li>
       <li onClick={() => revealList('meal')}>   Drinks  </li>
     </ul>    
    </div> 
    { cuisines amp;amp; 
         cuisines.map(cuisine => ( 
            <AdminCuisineList  label={cuisine.label} recipeHandler={() => this.revealRecipeList(cuisine.id)}} /> 
    ))} 

   { cuisine amp;amp; cuisine.recipes
         cuisine.recipes.map(recipe => ( 
            <AdminRecipeList  label=recipe.label} cuisineId={recipe.cuisine[0] /> 
    ))} 

  ); 

 }

}
  

Вот мои данные json для вызовов, которые я использую:
getCuisinesByCategory() ПОЛУЧАЕТ вызов
Вывод:

 [ 
  "label": "Indian",
  "category": "Meal", 
  "recipes": [ 
      { id: "123", "label": "Chicken Biryani"},
      { id: "124", "label": "Chicken Korma"}, 
      { id:  "125", "label: "Nihari"}, 
      { id: "1244", "label": "Pulao"}, 
      { id: "12321", "label": Pakore"},
      { id: "1232", "label": "Bun Kubab"}     
    ] 
]
  

Комментарии:

1. Admin.js вообще не используется recipes , только cuisine.recipes то, что не определено в коде… вы пытались создать действие и редуктор для DELETE_RECIPE_IN_CUISINE ?

2. Да, в Admin.js Я использую рецепты, вложенные в json-данные cuisine. Позвольте мне попробовать удалить DELETE_RECIPE_IN_CUISINE

Ответ №1:

Похоже, вы обрабатываете удаление рецептов в своем редукторе — вы используете неправильное действие при удалении своего рецепта. Вам нужно использовать свой тип действия DELETE_RECIPE. Вы используете GET_RECIPE_BY_ID

 export const deleteRecipe = (id) =>async dispatch => { 
 await axios.delete(`/api/recipe/${id})
 dispatch({
       type:DELETE_RECIPE,
       payload: id
 }); 
}