控制台日志中的 Mobx 状态更新,但不重新渲染
Mobx state updating in console log, but not re-rendering
我已经创建了一个 MobX 商店(React Native 项目)并且正在更新按钮点击时的状态值。状态已成功更新,如控制台日志中所示,但 DOM 未使用更新后的状态重新呈现。
关于 SO 的大多数答案都有点过时,因为他们建议在正确的位置添加 @observable
,但最新的 MobX 文档说使用不同的语法 makeAutoObservable(this, { key: value })
。
(EDIT: Codesandbox 所以你可以在 Home.js 中看到控制台登录按钮按下,但是“你爱......”没有更新与 mobx 存储值)
这是我当前的设置:
store.js
import { makeAutoObservable, observable } from "mobx";
export class ChooseTea {
tea;
constructor() {
makeAutoObservable(this, {
tea: observable,
});
}
selectTea = (tea) => {
this.tea = tea;
};
}
Home.js
import { ChooseTea } from "../data/store";
import { observer } from "mobx-react";
export const Home = observer(() => {
const store = new ChooseTea();
const handleChildChoose = (tea) => {
store.selectTea(tea); // value passed to store
console.log(store.tea); // successfully logs the new chosen tea
};
return (
<View style={styles.container}>
<Text>You love {store.tea}</Text> // does not update on new tea chosen
<View style={styles.teaCardContainer}>
{teaData &&
teaData.map((teaObj) => (
<TeaCard
id={teaObj.id}
teaData={teaObj}
key={teaObj.id}
strength={teaStrength * 2}
handleChoose={handleChildChoose}
/>
))}
</View>
</View>
);
});
TeaCard.js
function TeaCard({ teaData, handleChoose }) {
const handleClick = (tea) => {
handleChoose(tea); // value passed to parent component (Home.js)
};
return (
<View>
<View>
<Text>{teaData.name}</Text>
</View>
<Rating count={teaData.rating} />
<Button
title="Choose"
onPress={() => handleClick(teaData.name)}
color={AppStyles.colour.secondary}
/>
</View>
)
}
这一行是问题所在:
const store = new ChooseTea();
您正在重新创建您在每个渲染器上存储的内容。您的组件实际上对更改做出反应,开始重新渲染,但随后创建了新商店并且默认情况下未选择 tea
。因此,您正在更改旧商店中的数据,但随后使用新创建的商店中的数据。
您可以为您的商店使用 useState
或 useMemo
,例如:
const [store] = useState(() => new ChooseTea());
您还需要定义您的所有属性,否则它将无法工作(或者至少没有 extra configuration):
export class ChooseTea {
// Use null or empty string "", for example
tea = null;
constructor() {
makeAutoObservable(this);
}
selectTea = (tea) => {
this.tea = tea;
};
}
我已经创建了一个 MobX 商店(React Native 项目)并且正在更新按钮点击时的状态值。状态已成功更新,如控制台日志中所示,但 DOM 未使用更新后的状态重新呈现。
关于 SO 的大多数答案都有点过时,因为他们建议在正确的位置添加 @observable
,但最新的 MobX 文档说使用不同的语法 makeAutoObservable(this, { key: value })
。
(EDIT: Codesandbox 所以你可以在 Home.js 中看到控制台登录按钮按下,但是“你爱......”没有更新与 mobx 存储值)
这是我当前的设置:
store.js
import { makeAutoObservable, observable } from "mobx";
export class ChooseTea {
tea;
constructor() {
makeAutoObservable(this, {
tea: observable,
});
}
selectTea = (tea) => {
this.tea = tea;
};
}
Home.js
import { ChooseTea } from "../data/store";
import { observer } from "mobx-react";
export const Home = observer(() => {
const store = new ChooseTea();
const handleChildChoose = (tea) => {
store.selectTea(tea); // value passed to store
console.log(store.tea); // successfully logs the new chosen tea
};
return (
<View style={styles.container}>
<Text>You love {store.tea}</Text> // does not update on new tea chosen
<View style={styles.teaCardContainer}>
{teaData &&
teaData.map((teaObj) => (
<TeaCard
id={teaObj.id}
teaData={teaObj}
key={teaObj.id}
strength={teaStrength * 2}
handleChoose={handleChildChoose}
/>
))}
</View>
</View>
);
});
TeaCard.js
function TeaCard({ teaData, handleChoose }) {
const handleClick = (tea) => {
handleChoose(tea); // value passed to parent component (Home.js)
};
return (
<View>
<View>
<Text>{teaData.name}</Text>
</View>
<Rating count={teaData.rating} />
<Button
title="Choose"
onPress={() => handleClick(teaData.name)}
color={AppStyles.colour.secondary}
/>
</View>
)
}
这一行是问题所在:
const store = new ChooseTea();
您正在重新创建您在每个渲染器上存储的内容。您的组件实际上对更改做出反应,开始重新渲染,但随后创建了新商店并且默认情况下未选择 tea
。因此,您正在更改旧商店中的数据,但随后使用新创建的商店中的数据。
您可以为您的商店使用 useState
或 useMemo
,例如:
const [store] = useState(() => new ChooseTea());
您还需要定义您的所有属性,否则它将无法工作(或者至少没有 extra configuration):
export class ChooseTea {
// Use null or empty string "", for example
tea = null;
constructor() {
makeAutoObservable(this);
}
selectTea = (tea) => {
this.tea = tea;
};
}