React / Reduxで、シンプルなショッピングカートアプリを作成しようとしています。
ローカルのJSONファイルからデータを読み込み、カートに入れるを押した商品がカートの中に入り、合計金額が計算され、カートから削除を押すと、削除されるようにしたいと考えています。
現時点では、カートに入れるアイテムは、stateに addedItems: [] というようなarrayを作って、actionを通じて商品を追加したいと思っているのですが、JSONデータ以外のstateを作る方法がわかりません。
reducerに、INITIAL_STATEというvariableを作り、
import data from 'data.json'; const INITIAL_STATE = { items: data, addedItems: [], total :0 } const cartReducer = (state = INITIAL_STATE, action) => { switch (action.type) { ......
としてみたのですが、すると、商品一覧を表示させようとした時に map が使用できませんとエラーになってしまいました。
【追記】
どうやら私が求めていたaddedItemsの[]は、itemsの中にあったようです。
stateの構造としては、
items
┗items: [...]
┗addedItems:[]
┗total: 0
となっていて、mapは、this.props.items.items.slice(0, 20).mapでアクセスできました。ですが、itemsにくるませるのではなく、3つのstateは何にもくるまれない状態にしたいです。
Action Creator export const addToCart = (id) => { return { type: ADD_ITEM_TO_CART, id } } export const removeFromCart = (id) => { return { type: REMOVE_ITEM_FROM_CART, id } }
Reducer import data from "../data.json"; import { ADD_ITEM_TO_CART, REMOVE_ITEM_FROM_CART } from '../actions/types'; const cartReducer = (state = data, action) => { switch (action.type) { case ADD_ITEM_TO_CART: let addedItem = state.items.find(item => item.id === action.id); return { ...state, addedItem: [...state.addedItem, addedItem] } case REMOVE_ITEM_FROM_CART: return {} default: return state; } } export default cartReducer;
Reducer import { combineReducers } from 'redux'; import items from './cartReducer'; export default combineReducers({ items })
Component #1 import React from 'react'; import { connect } from 'react-redux'; import { addToCart } from '../actions'; class ItemList extends React.Component { handleClick = (id) => { this.props.addToCart(id) } renderList() { console.log(this.props.items) return this.props.items.slice(0, 20).map(item => { return ( <div className="card" key={item.id}> <span className="card-title">{item.name}</span> <span to="/" style={{bottom: "10px"}} className="btn-floating halfway-fab waves-effect waves-light red" onClick={() => this.handleClick(item.id)} > <i className="material-icons">add</i> </span> <p>{item.content}</p> <p><b>Price: {item.price}$</b></p> </div> ) }) } render() { console.log(this.props) return ( <div className="container" style={{float:"left", width: "700px"}}> <h3 className="center">Our items</h3> <div className="box"> {this.renderList()} </div> </div> ) } } const mapStateToProps = state => { return { items: state.items } } const mapDispatchToProps = dispatch => { return { addToCart: (id) => { dispatch(addToCart(id)) } } } export default connect(mapStateToProps, mapDispatchToProps)(ItemList);
component #2 import React from 'react'; import { connect } from 'react-redux'; class Cart extends React.Component { render() { console.log('Cart.js', this.props.items) // let addedItems = this.props.items.length ? // ( // <p>It has something</p> // ) : // ( // <p>Nothing.</p> // ) return ( <div> test </div> ) } } const mapStateToProps = state => { return { items: state.items } } export default connect(mapStateToProps)(Cart); // export default Cart;
data.json [ { "id": 201, "name": "Nulla", "price": 207, "subCategoryId": 101, "categoryId": 1, "rate": 2.44, "content": "Culpa sed tenetur incidunt quia veniam sed mollitia exercitationem. Laboriosam reprehenderit laborum pariatur ea rem qui inventore. In asperiores dignissimos temporibus et. Beatae consequatur corrupti nam praesentium.", "review": 78, "typeVariant": "D", "colorVariant": "5", "imageUrl": "https://placeholdit.imgix.net/~text?txtsize=55&txt=137x945&w=137&h=945" },{ "id": 202, "name": "Corporis", "price": 271, "subCategoryId": 101, "categoryId": 1, "rate": 2.18, "content": "Nam incidunt blanditiis odio inventore. Nobis voluptatum quibusdam laboriosam a numquam. Delectus sequi ipsa possimus ratione repellendus quibusdam. Molestiae fuga laudantium natus dolorem.", "review": 67, "typeVariant": "A", "colorVariant": "4", "imageUrl": "https://dummyimage.com/931x785" },{ "id": 203, "name": "Minus", "price": 295, "subCategoryId": 101, "categoryId": 1, "rate": 0.91, "content": "Quod reiciendis aspernatur ipsum cum debitis. Quisquam tempore doloremque quo ipsum ipsa tempora. Dignissimos qui ex ad facilis. Quo sequi recusandae eveniet autem ducimus nam.", "review": 116, "typeVariant": "E", "colorVariant": "2", "imageUrl": "https://dummyimage.com/556x985" } ]
どのように解決したらいいか、アドバイスをいただければ幸いです。
回答2件
あなたの回答
tips
プレビュー