I'm completely confused with the rules of mobX - react . Some methods in another project work, but not in this test.
Below is the code of my components from the test application
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;
ComponentFirst
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;
ComponentSecond
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();
My question
My App component is subscribed via observe to changes in stores. By clicking on the first button, in 1 component the text in the storage and, accordingly, the text should change, but it does not change. And In the second component, the value for the text field is taken from testStoreSecond. There, the text field is taken from testStoreFirst . When the button is clicked, the method from testStoreFirst is executed which should change the text, but it does not change.
I've read the documentation, but I still don't fully understand how to use the store and achieve "reactivity" and instant change of the component.
You need to wrap every component that uses any observable values with observer
decorator, like you did with an App
. But in case of App
it's actually useless because you are not using observable values there. So just wrap other components and it should work fine.
As for this line textFromFirstStore = testStoreFirst.textForSecondTestStore
it won't work like you expected because you just assigned value of testStoreFirst.textForSecondTestStore
to textFromFirstStore
and that's it.
To make such value reactive you need to use computed
value. To make computed
you just need to setup a getter function, like that:
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>