控制台日志中的 Mobx 状态更新,但不重新渲染

时间:2021-03-15 08:52:39

标签: javascript reactjs react-native mobx mobx-react

我已经创建了一个 MobX 商店(React Native 项目)并且正在更新按钮单击时的状态值。状态已成功更新,如控制台日志中所示,但 DOM 未使用更新后的状态重新呈现。

SO 上的大多数答案都有些过时,因为他们建议在正确的位置添加 @observable,但最新的 MobX 文档说对 makeAutoObservable(this, { key: value }) 使用不同的语法。

编辑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>
  )
}

1 个答案:

答案 0 :(得分:1)

这一行是问题所在:

const store = new ChooseTea();

您在每次渲染时都在重新创建您的存储。您的组件实际上对更改做出反应,开始重新渲染,但随后会创建新存储并且默认情况下未选择 tea。因此,您正在更改旧存储中的数据,然后使用新创建的存储中的数据。

您可以做的是为您的商店使用 useStateuseMemo,如下所示:

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;
  };
}

Codesandbox