javascript - Mobx 状态不更新
问题描述
我有 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)
我花了很多时间试图了解问题所在,但我无法
解决方案
您的描述和代码很难理解。我建议进行以下更改:
runInAction
用这样的异步方法包装:
axios.get("http://localhost:3000/db.json")
.then((resp)=> {
runInAction(() => {
this.setPizzas(resp.data.pizzas)
})
}
- setWeight、setSize 和 setPrice 方法可能应该是 getter(mobx 计算,而不是动作)。在方法之前添加
get
并删除()
括号。例子:
get setWeight() {
return ...
}
然后在你使用它的地方:
pizzaStore.setWeight
控制台上是否有任何错误?
推荐阅读
- wordpress - Google Cloud Balancing 上的 WordPress 和负载平衡
- objective-c - Rust bindgen clang 错误,此 __builtin_neon 函数的常量不兼容
- reactjs - 尝试将我的应用程序添加到浏览器中的 chrome 应用程序时,chrome 错误地显示我的旧应用程序名称
- node.js - 检测用户何时离开浏览器
- django - 从原始 django SQL 查询中获取文件 URL
- laravel - 如何在 Backpack for Laravel 中管理用户对特定数据的权限?
- wordpress - 为什么提交表单时会出错?
- javascript - 如何从我发布的 npm 包中访问图像和声音?
- javascript - 当悬停在一个圆圈上时,动画一个圆圈和连接它们的线条的 svg
- activejdbc - ActiveJdbc 无法包含表