簡體   English   中英

Mobx 狀態不更新

[英]Mobx state does not update

我有 2 個 mobx 商店,一個是產品,一個是購物車,還有一個模態窗口 React 組件。 我需要做的是使用產品商店方法將屬性放入模態窗口,然后將所有屬性以對象的形式推送到購物車商店中的數組中。 問題是我檢查數組中是否已經存在一個對象,但即使你選擇了不同的屬性,最終狀態還是保持不變,數組不讓對象進入。 大小和價格等狀態根本不會改變。

以下是代碼片段:

產品商店:

import axios from "axios";
import {makeAutoObservable} from "mobx";
class PizzaStore {
    weight:number=200;
    size:number=20;
    pizzas:Object[]=[];
    modalProps:any={};
    constructor(){
        makeAutoObservable(this);
    }
    setModalProps=(p:Object)=>{this.modalProps=p};
    setPizzas=(pizzaArr:any)=>{
        this.pizzas=pizzaArr}
    fetchPizzas=()=>{
        axios.get("http://localhost:3000/db.json").then((resp)=>{
    this.setPizzas(resp.data.pizzas);})}
    setWeight=(option:string)=>{
        switch (option){
            case "small":return this.weight;
            case "medium":return this.weight*1.5;
            default:return this.weight*2;
        }
    }
    setSize=(opt:string)=>{
        switch (opt){
            case "small":return this.size
            
            case "medium":return this.size*1.5;
           
            default:return this.size*2;
        }
    }
    setPrice=(opt:string, price:number)=>{
        switch (opt){
            case "small":return price;
            case "medium":return price*1.5;
            default:return price*2;
        }
    }}
const pizzaStore=new PizzaStore();

export default pizzaStore;
        

購物車商店:

import { makeAutoObservable } from "mobx";
interface p{
    p:object,
}
class CartStore{
    cartItems:any=[]
    cartPrice:number=0;
    constructor(){
        makeAutoObservable(this);
    }
    handleSubmitForm=(e:any, p:{})=>{
        e.preventDefault();
        this.handleSubmitProps(p);
    }
    handleSubmitProps=(p:any)=>{
        if(this.cartItems.some((item:any)=>{return item.modalName===p.modalName&&item.modalSize===p.modalSize})){
            console.log(p.modalName, p.modalSize, p.modalPrice)
        }
           
            else{
                console.log("pushed")
                this.cartItems.push(p);
                console.log(p.modalPrice)
            }
            
        }
        
        
   }
    

const cartStore=new CartStore();
export default cartStore;

和模態窗口組件:

import React from 'react'
import pizzaStore from './stores/PizzaStore'
import {observer} from "mobx-react-lite"
import cartStore from './stores/CartStore';
import { action } from 'mobx';

function ModalWindowComponent({activeModal, setActiveModal}:any){
    
    const [selectedOption, setSelectedOption]=React.useState("small")
    const handleSetOption=(e:any)=>{
            setSelectedOption(e.target.value)
        }
        let modalImageUrl=pizzaStore.modalProps.imageUrl
        let modalName=pizzaStore.modalProps.name
        let modalDesc=pizzaStore.modalProps.description
        let modalSize=pizzaStore.setSize(selectedOption)
        let modalPrice=pizzaStore.setPrice(selectedOption, pizzaStore.modalProps.price)

    return (
        <div className={activeModal?"modal active":"modal"}  onClick={()=>{setActiveModal(false); setSelectedOption("small")}}>
            <div className="modal-content" onClick={(e)=>{e.stopPropagation()}}>
                <div className="modal-content-header">
                    <button onClick={()=>setActiveModal(false)}>Close</button>
                </div>
                <img src={modalImageUrl} className="modal-content-img"/>
                <p className="modal-content-pizza-name">{modalName}</p>
                <p className="modal-content-pizza-desc">{modalDesc}</p>
                <p className="modal-content-pizza-size">{pizzaStore.setSize(selectedOption)}см</p>
                <p className="modal-content-pizza-weight">{pizzaStore.setWeight(selectedOption)}грамм</p>
                <p className="modal-content-pizza-price">{modalPrice}Руб.</p>
                <form className="modal-content-sizes-form" onSubmit={action((e)=>cartStore.handleSubmitForm(e, {modalName, modalDesc, modalSize, modalPrice, modalImageUrl}))}>
                    <label>
                    
                    <input  name="radio-size"value="small" type="radio" onChange={handleSetOption} checked={!activeModal||selectedOption==="small"} className="modal-content-sizes-form-option"/>Маленькая</label>
                    <label>
                    <input  name="radio-size"value="medium" type="radio"  onChange={handleSetOption}checked={selectedOption==="medium"}className="modal-content-sizes-form-option"/>Средняя</label>
                    <label>
                    <input name="radio-size"value="big" type="radio"  onChange={handleSetOption}checked={selectedOption==="big"} className="modal-content-sizes-form-option"/>Большая</label>
                    <button onClick={()=>{setSelectedOption("small");setActiveModal(false);console.log(cartStore.cartItems)}}>Добавить</button>
                </form>
            </div>
        </div>
    )
}

export default observer(ModalWindowComponent)

我花了很多時間試圖了解出了什么問題,但我做不到

您的描述和代碼很難理解。 我建議進行這些更改:

  1. runInAction在這樣的異步方法中:
    axios.get("http://localhost:3000/db.json")
      .then((resp)=> {
           runInAction(() => {
               this.setPizzas(resp.data.pizzas)
           })
       }
  1. setWeight、setSize 和 setPrice 方法可能應該是 getter(mobx 計算,而不是 action)。 在方法之前添加get並刪除()括號。 例子:
get setWeight() {
   return ...
}

然后在你使用它的地方:

pizzaStore.setWeight

控制台上是否有任何錯誤?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM