如何在 React 17 中使用 Mobx 6 存储?

How use Mobx 6 storage with React 17?

我完全搞不懂 mobX 的规则 - react 。其他项目中的某些方法有效,但在本次测试中无效。

下面是测试应用程序中我的组件的代码

App.js

import React, { FC } from 'react';
import "./App.css";
import {observer} from 'mobx-react';
import ComponentFirst from './components/ComponentFirst/ComponentFirst';
import ComponentSecond from './components/ComponentSecond/ComponentSecond';


const App: FC = observer(() => {
  return (
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <ComponentFirst />
        <ComponentSecond />
      </div>
  );
})

export default App;

组件优先

import React, { FC } from 'react';
import {testStoreFirst} from '../../stores/testStoreFirst';

const ComponentFirst : FC = () => {
    return (
        <div>
            <h3>It is First Component</h3>
            <p>{testStoreFirst.testText}</p>
            <p>{testStoreFirst.textForSecondTestStore}</p>
            <button onClick={() => {testStoreFirst.setTestText('New text after click')}}>Click me!!!</button>
        </div>
    )
}

export default ComponentFirst;

第二个组件

import React, { FC } from 'react';
import {testStoreSecond} from '../../stores/testStoreSecond';
import {testStoreFirst} from '../../stores/testStoreFirst';

const ComponentSecond : FC = () => {
    return (
        <div>
            <h3>It is Second Component</h3>
            <p>{testStoreSecond.textFromFirstStore}</p>
            <button onClick={() =>{testStoreFirst.setTextForSecondTestStore('I can change text from second storage')}}>Click me!!!</button>
        </div>
    )
}

export default ComponentSecond;

testStoreFirst

import { makeAutoObservable} from "mobx";

class TestStoreFirst  {
    testText='It is test text from mobX storage';
    textForSecondTestStore='this text from First Store!!!';

    constructor() {
        makeAutoObservable(this);
    }


    setTextForSecondTestStore = (newText : string) => {
        this.textForSecondTestStore = newText;
    }

    setTestText = (newText: string) => {
        this.testText = newText;
        console.log('It is not work');
    }

}

export const testStoreFirst = new TestStoreFirst()

testStoreSecond

import {makeAutoObservable} from 'mobx'
import {testStoreFirst} from './testStoreFirst'

class TestStoreSecond {
    textFromFirstStore = testStoreFirst.textForSecondTestStore

    constructor() {
        makeAutoObservable(this);
    }
}

export const testStoreSecond = new TestStoreSecond();

我的问题

我的 App 组件是通过观察商店的变化来订阅的。通过单击第一个按钮,在 1 组件中,存储中的文本和相应的文本应该更改,但它不会更改。在第二个组件中,文本字段的值取自 testStoreSecond。在那里,文本字段取自 testStoreFirst 。单击按钮时,将执行 testStoreFirst 中的方法,该方法应该更改文本,但它没有更改。

我已经阅读了文档,但我仍然没有完全理解如何使用商店并实现组件的“反应性”和即时更改。

您需要使用 observer 装饰器包装每个使用任何可观察值的组件,就像您对 App 所做的那样。但是在 App 的情况下它实际上是无用的,因为你没有在那里使用可观察的值。所以只需包装其他组件,它应该可以正常工作。

至于这一行 textFromFirstStore = testStoreFirst.textForSecondTestStore 它不会像您预期的那样工作,因为您只是将 testStoreFirst.textForSecondTestStore 的值分配给 textFromFirstStore 而已。

要使此类值具有反应性,您需要使用 computed 值。要制作 computed 你只需要设置一个 getter 函数,就像这样:

class TestStoreSecond {
  // ...

  get textFromFirstStore() {
    return testStoreFirst.textForSecondTestStore
  }

  // ...
}

// And in React access it just as before (it's a getter, not a function)
<p>{testStoreSecond.textFromFirstStore}</p>