繁体   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