【发布时间】:2021-11-25 10:02:40
【问题描述】:
我目前正在学习 redux,我正在尝试通过创建个人项目来学习。这个想法是创建一个食谱应用程序,用户可以在其中查看食谱、保存他们喜欢的食谱并将他们喜欢的食谱导出到购物清单。
为了渲染食谱,我使用了两个组件。一个组件是单个配方,另一个组件使用单个配方组件映射不同的配方。我将两者拆分为单独的组件的原因是我希望映射不同配方的组件能够被重用以映射用户最喜欢的配方(避免编写额外的代码来基本上执行相同的过程,即渲染一个数组里面有不同的食谱)。
为了保存最喜欢的食谱,我想使用 redux,因为这(据我了解)允许我将状态分派到不同的组件(使用 mapStateToProps 和连接)。这应该允许我(如果我错了,请纠正我)在映射不同食谱的组件中使用 favoriteRecipes 的状态。我还可以使用单个食谱组件中的状态来创建一个按钮,用于将不同的食谱添加到我的收藏夹中。由于某种原因,我无法让 dispatch/redux 工作。在 redux devtools 中,我可以看到初始状态(一个空数组),但是一旦我尝试将配方添加到 favoriteRecipe 数组中,什么都没有发生。我已经尝试让它工作了几天,但似乎没有任何效果。
提前感谢您帮助我!
第一个文件:/redux/favoriteRecipes/favoriteRecipesTypes.js
export const ADD_TO_FAVORITE_RECIPES = 'ADD_TO_FAVORITE_RECIPES';
export const REMOVE_FROM_FAVORITE_RECIPES = 'REMOVE_FROM_FAVORITE_RECIPES';
export const CLEAR_FAVORITE_RECIPES = 'CLEAR_FAVORITE_RECIPES';
第二个动作创建者:/redux/favoriteRecipes/favoriteRecipesActions/js
import { ADD_TO_FAVORITE_RECIPES, REMOVE_FROM_FAVORITE_RECIPES, CLEAR_FAVORITE_RECIPES } from "./favoriteRecipesTypes";
export const addToFavoriteRecipes = (recipe) => {
return {
type: ADD_TO_FAVORITE_RECIPES,
payload: recipe
}
}
export const removeFromFavoriteRecipes = (recipe) => {
return {
type: REMOVE_FROM_FAVORITE_RECIPES,
payload: recipe
}
}
export const clearFavoriteRecipes = () => {
return{
type: CLEAR_FAVORITE_RECIPES
}
}
第三个reducer:/redux/favoriteRecipes/favoriteRecipesReducer.js
import { ADD_TO_FAVORITE_RECIPES, REMOVE_FROM_FAVORITE_RECIPES, CLEAR_FAVORITE_RECIPES } from "./favoriteRecipesTypes";
const initialFavoriteRecipes = {
favoriteRecipes: []
}
const favoriteRecipesReducer = (state = initialFavoriteRecipes, action) => {
switch(action.type) {
case ADD_TO_FAVORITE_RECIPES:
return {
...state,
favoriteRecipes: [...state.favoriteRecipes, action.payload]
}
case REMOVE_FROM_FAVORITE_RECIPES:
return {
...state,
favoriteRecipes: state.favoriteRecipes.filter(item => item !== action.payload)
}
case CLEAR_FAVORITE_RECIPES:
return {
...state,
favoriteRecipes: []
}
default:
return state
}
}
export default favoriteRecipesReducer;
第四个商店:/redux/store.js
import { createStore, applyMiddleware, compose} from "redux";
import favoriteRecipesReducer from "../redux/favoriteRecipes/favoriteRecipesReducer";
import logger from "redux-logger";
const store =
createStore(
favoriteRecipesReducer,
compose(
applyMiddleware(logger),
window.devToolsExtension ? window.devToolsExtension() : f => f
)
)
export default store;
第五:单个配方组件(我省略了一些部分以使其尽可能简短):
import React, {useState} from 'react';
import {connect} from 'react-redux';
import { addToFavoriteRecipes } from '../../redux/favoriteRecipes/favoriteRecipesActions';
export const Recipe = ({recipe}, props) => {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="col-md-3">
<div className="card bwm-card">
<div className="card-title">
<h2>{recipe.title}</h2>
</div>
<img className="card-img-top" src={recipe.image} alt={recipe.title} />
<div className="card-subtitle">
<h3>
<b>Type: {recipe.type} </b>
</h3>
<h3>
<b>Category: {recipe.category}</b>
</h3>
<h3>
<b>Cooking time: {recipe.cookingTime} minutes</b>
</h3>
</div>
<div>//omitted part: show or hide full recipe depending on the state of isOpen</div>
<div>
<input type="submit" onClick={props.addToFavoriteRecipes} value="add to favorite recipe" />
</div>
</div>
</div>
);
};
const mapStateToProps = state => {
return{
favoriteRecipes: state.favoriteRecipes
}
}
const mapDispatchToProps = dispatch => {
return{
addToFavoriteRecipes: () => dispatch(addToFavoriteRecipes())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Recipe)
【问题讨论】:
-
通常请注意,您使用的是非常古老的 Redux 风格。现代 Redux 使用钩子而不是连接,并且没有 switch..case 减速器、ACTION_TYPES、不可变减速器逻辑或 createStore。查看官方 Redux 教程redux.js.org/tutorials/essentials/part-1-overview-concepts 了解更多信息。
标签: javascript reactjs redux react-redux