2017-11-06 17 views
0

特定のオブジェクトを更新するためにsetStateを使用していますが、何らかの理由でsetState関数に追加していないにもかかわらず、プロンプトを表示せずに状態内のオブジェクトが変化しています

基本的には、カート状態オブジェクトにアイテムがすでに存在する場合は、そのアイテムの数を1だけ増分します。そうでない場合は、カートの状態をそのアイテムを含むコピーで更新します。

this.state = { 
    items: { 
    0: { name: 'Red shirt', price: 10 }, 
    1: { name: 'Blue shirt', price: 11 }, 
    2: { name: 'Green shirt', price: 12 }, 
    3: { name: 'Yellow shirt', price: 13 } 
    }, 
    cart: {}, 
    user: {} 
} 

addToCart = (key, item) => { 
let newCart; 
newCart = this.state.cart; 

// item already exists in cart 
if (newCart[key]) { 
    // increment qty of added item 
    newCart[key].qty++; 
    // does not exist, need to add to cart 
} else { 
    newCart[key] = item; 
    newCart[key].qty = 1; 
} 
this.setState({ cart: newCart }); 
} 

    render() { 
const { cart, items } = this.state; 
return (
    <div className="App"> 
    <h1>Streat</h1> 
    <Checkout cart={cart} /> 
    <Items 
     items={items} 
     addToCart={this.addToCart} 
    /> 
    </div> 
); 
} 
} 

// Items component which holds Item component 
class Items extends Component { 
constructor(props) { 
    super(props) 
} 

render() { 
    const { items, addToCart } = this.props; 
    return (
     <div> 
      { 
       map(items, function renderItems(item, key) { 
        return <Item 
         item={item} 
         itemRef={key} 
         key={key} 
         addToCart={addToCart} /> 
       }) 
      } 
     </div> 
    ) 
} 
} 

// Item functional component which has the add to cart button 
const Item = (props) => { 
const { item, itemRef, addToCart } = props; 
return (
    <div> 
     <p>{item.name}</p> 
     <p>{item.price}</p> 
     <p>{item.qty || ""}</p> 
     <button onClick={() => addToCart(itemRef, item)}>Add</button> 
    </div> 
) 
} 

私の項目の状態を検査することで、開発者ツールを反応させるオブジェクトのとき、私は数量を更新/私はカートにアイテムを追加するためのボタンをクリックするたびに、それは正しくカートにアイテムを追加しないことを確認私の状態でitemsオブジェクトのアイテムを更新し、 'qty'キー/値のペアを追加します。これは私が望むものではありません。

私のカートのオブジェクトにsetStateを使用していますが、アイテムオブジェクトも何らかの理由で変更されています。

+0

あなたは – Geeky

+0

@Geekyが行わあなたに総コードを追加することができます:)! – jonathanpuc

答えて

2

spread syntaxを使用して状態を更新しようとすると、この種の問題に陥ることはありません。 Reduxもそれを多く使用しています。それを行うことで、あなたのオブジェクトを突然変異させず、それらのクリーンなコピーを作成します。

コードnewCart[key] = item;)をコピーしていません。代わりに、同じアイテムからの参照を入れていて、次の行のqtyを変更すると、itemsキーにも同様に更新されます。

const Item = ({ name, price, onClick }) => 
 
    <div onClick={onClick}> 
 
    {name} {price} 
 
    </div> 
 

 
class App extends React.Component { 
 
    constructor() { 
 
    super() 
 

 
    this.state = { 
 
     items: { 
 
     0: { name: 'Red shirt', price: 10 }, 
 
     1: { name: 'Blue shirt', price: 11 }, 
 
     2: { name: 'Green shirt', price: 12 }, 
 
     3: { name: 'Yellow shirt', price: 13 } 
 
     }, 
 
     cart: {}, 
 
     user: {} 
 
    } 
 
    } 
 
    
 
    addToCart(key, item) { 
 
    const hasItem = this.state.cart[key] 
 
    
 
    this.setState({ 
 
     ...this.state, 
 
     cart: { 
 
     ...this.state.cart, 
 
     [key]: { 
 
      ...(hasItem ? this.state.cart[key] : item), 
 
      qty: hasItem ? this.state.cart[key].qty + 1 : 1, 
 
     }, 
 
     }, 
 
    }) 
 
    } 
 

 
    render() { 
 
    const { cart, items } = this.state 
 
     
 
    return (
 
     <div> 
 
     <div>Click to add:</div> 
 
     {Object.keys(items).map(key => 
 
      <Item 
 
      {...items[key]} 
 
      key={key} 
 
      onClick={this.addToCart.bind(this, key, items[key])} 
 
      /> 
 
     )} 
 
     
 
     <div style={{ marginTop: 20 }}> 
 
      {Object.keys(cart).map(key => 
 
      <div key={key}>{cart[key].name}:{cart[key].qty}</div> 
 
     )} 
 
     </div> 
 
     </div> 
 
    ) 
 
    } 
 
} 
 

 
ReactDOM.render(
 
    <App />, 
 
    document.getElementById('root') 
 
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id="root"></div>

+0

そのブロックが正当な解決策(didnt work)であることを意図しているのか、それとも単なる提案なのかは不明です。私は、普及している構文の仕方を見て、それが何か変わるかどうかを見てみましょう。 – jonathanpuc

+0

@jonathanpucはい、それは解決策です。私の作業サンプルを確認してください:) – mersocarlin

+0

うわあ、うまく動作します、ありがとう。 私は非常にかかわらず、ここで何が起こっているのか理解していない: [キー]:{ ...(hasItem [キー] this.state.cart:?アイテム)を、 数量:hasItem? this.state.cart [key] .qty + 1:1、 } 2行目でスプレッド演算子がどのように使われているのか分かりません。説明していただけますか? :) – jonathanpuc

関連する問題