reactjs - 如何在 Redux 中创建另一个包含两个 reducer 的状态来更新状态
问题描述
我正在使用 React/Redux 创建一个电影应用程序,它允许用户通过单击一个按钮(买票)来选择一部电影,该按钮将用户带到另一个页面以选择票的数量并将他的购买添加到购物车.
这个想法是当用户点击按钮添加到卡片时,我希望发生两件事,一是应该在导航栏中的徽章购物车中更新数量,如果用户想要结帐,还应该将此电影添加到包中.
当我单击添加到购物车时,如何在减速器中创建一个名为购物车的状态来更新数量并将电影添加到该购物车中?
你怎么看?
<-- 动作类型-->
export const ActionsTypes = {
SET_MOVIES : "SET_MOVIES",
GET_MOVIE : "GET_MOVIE",
REMOVE_MOVIE : "REMOVE_MOVIE",
QUANTITY: "QUANTITY",
}
<-- 数量动作-->
export const MovieQuantity = () => {
return {
type : ActionsTypes.QUANTITY
}
}
<-- 减速器-->
const initialState = {
movies: [],
};
//Movies Reducers
export const setMoviesReducers = (state = initialState, action) => {
switch (action.type) {
case ActionsTypes.SET_MOVIES:
return {...state, movies: action.payload }
default:
return state;
}
}
// single Movies Reducers
export const GetMovieDetailsReducers = (state={}, action) => {
switch(action.type) {
case ActionsTypes.GET_MOVIE :
return {...state, ...action.payload}
case ActionsTypes.REMOVE_MOVIE :
return {};
default :
return state
}
}
export const movieQuantityReducers = (state = 0 , action) => {
switch(action.type) {
case ActionsTypes.QUANTITY:
return state + 1;
default :
return state;
}
}
<-- 电影详情添加到购物车组件-->
const MovieDetails = () => {
const [quantity, setQuantity] = useState(1)
const singleMovie = useSelector((state)=> state.movie);
const quantityBag = useSelector((state)=> state.quantity);
const {title, poster_path, overview} = singleMovie;
const dispatch = useDispatch();
let {movieId} = useParams();
// Handle Click Quantity
const handleQuantity = (type) => {
if(type === "dec") {
quantity > 1 && setQuantity(quantity - 1)
} else {
setQuantity(quantity + 1)
}
}
// add to cart Handler
const CartHandler = () => {
dispatch(MovieQuantity(quantityBag)) // the quantity is just incrementing
}
// Get a single Product & Remove product
useEffect(()=> {
try {
const getSingleMovie = async () => {
const request = await axios.get(`https://api.themoviedb.org/3/movie/${movieId}?api_key=&&&&&`);
const response = await request.data;
dispatch(getMovie(response))
}
getSingleMovie();
} catch(error) {
console.log(`ERROR : ${error}`)
}
//Clean up
return () => {
dispatch(removeMovie());
}
}, [movieId])
return (
<section className="movieDetails_container">
<div className="wrapper">
<div className="img-container">
<img src={`${ImgPath}` + poster_path} alt={title}/>
</div>
<div className="info-container">
<h1>{title}</h1>
<p>{overview}</p>
<div className="quantity-container">
<Remove className="quantity-icon" onClick={()=> handleQuantity("dec")}/>
<span className="amount">{quantity}</span>
<Add className="quantity-icon" onClick={()=> handleQuantity("incr")}/>
</div>
<button className="btn-add" onClick={()=> CartHandler()}>Add To Cart</button>
</div>
</div>
</section>
)
}
export default MovieDetails
<-- 导航栏组件 -->
const Navbar = () => {
const quantityBag = useSelector((state)=> state.quantity);
return (
<nav className="navBar-section">
<Link to="/">
<h1 className="logo">映画館</h1>
</Link>
<Badge badgeContent={quantityBag} color="primary">
<LocalMall className="icon-bag" />
</Badge>
</nav>
)
}
export default Navbar
解决方案
我会以不同的方式对状态进行建模。根据您的描述,以下内容会很好地工作:
const state = {
// movie details reducer handles this part:
movies: {
"movie1Id": {
"name": "Title of movie1"
// more movie details here
},
"movie2Id": {
"name": "Title of movie2"
// more movie details here
},
},
// cart reducer handles this part:
cart: {
"movie1Id": 3, // quantity. user chose 3 tickets for movie1.
"movie2Id": 1, // quantity. user chose 1 ticket for movie2.
}
};
const setCartItemAction = (movieId, quantity) => ({
type: "SET_CART_ITEM",
payload: { movieId, quantity }
});
这setCartItemAction
足以为您的用例建模。为某部电影调用它的数量与0
从购物车中删除该电影相同。
推荐阅读
- javascript - 在服务器-客户端往返期间存储(或传递)Element/TableCell 引用
- sql - 数据仓库模型方法
- java - spring-ws : Wss4jSecurityInterceptor UserNameToken 以及 Signature securementActions
- python-3.x - 分块后删除部分语音标签
- docker - 两个独立的 Docker-Compose-Files 和对共享文件夹的访问
- python - 如何使用 tkinter python 实现暂停和恢复按钮功能
- redis - Redis sorted set 排行榜排名同分
- android - 在构建器方法中强制方法调用
- wordpress - 如何在点击类别页面 wordpress 类别上显示子类别
- javascript - 从控制器执行所有代码后,如何在Spring mvc中从控制器获取数据标志到jsp