【问题标题】:Re-rending component when the state changes in a different reducer当状态在不同的 reducer 中改变时重新渲染组件
【发布时间】:2019-04-09 21:34:39
【问题描述】:

Okies,所以,我正在开发一个简单的食谱集合应用程序,其中我有 foodReducer.js 和 RecipeReducer.js。

在我的管理仪表板上,管理员用户可以创建、删除和编辑任何美食组,还可以创建、删除和编辑任何美食组的食谱。 当用户点击任何菜系组时,它会使用菜系 ID 呈现菜谱面板中的所有菜谱。用户也可以通过在食谱或美食组上按“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 && 
         cuisines.map(cuisine => ( 
            <AdminCuisineList  label={cuisine.label} recipeHandler={() => this.revealRecipeList(cuisine.id)}} /> 
    ))} 

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

  ); 

 }

}

这是我正在使用的调用的 json 数据: getCuisinesByCategory() GET 调用 输出:

[ 
  "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"}     
    ] 
]

【问题讨论】:

  • Admin.js 根本不使用recipes,只有代码中未定义的cuisine.recipes...您是否尝试为DELETE_RECIPE_IN_CUISINE 创建动作和reducer?跨度>
  • 是的,在 Admin.js 中,我使用嵌套在美食 json 数据中的食谱。让我试试删除 DELETE_RECIPE_IN_CUISINE

标签: reactjs react-redux react-lifecycle react-lifecycle-hooks


【解决方案1】:

看起来您在 reducer 中处理了删除配方 - 您在删除配方时使用了错误的操作。您需要使用您的 DELETE_RECIPE 操作类型。您正在使用 GET_RECIPE_BY_ID

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

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 2019-08-08
    • 1970-01-01
    • 2018-11-30
    • 2020-04-22
    • 2014-09-30
    • 1970-01-01
    • 2020-01-20
    • 2020-12-30
    相关资源
    最近更新 更多