reactjs - komponenten renderas inte om när tillståndet uppdateras i mobx
Jag försöker förstå varför min app inte renderar om när jag ändrar mitt state i mobx-observable-namn arrayen. Jag ändrar värdet med input-taggen. Skulle uppskatta lite hjälp :)
observatörskomponent:
import {observable, action, autorun, computed} from 'mobx'
class TodosStore {
@observable names = ["p1", "p2", "p3"]
@observable filter = ""
@action
get filterredValue(){
return store.names.filter(word => word.includes(this.filter))
}
}
//@ts-ignore
var store = window.store = new TodosStore
export default store
autorun(() => {
console.log(store.filter);
console.log(store.names);
})
och detta är min appkomponent:
import React from 'react';
import './App.css';
import store from './components/observers'
class App extends React.Component {
constructor(props :any) {
super(props);
this.setName = this.setName.bind(this);
}
setName = (e : any) => {
store.filter = e.target.value
}
render() {
return (
<div className="App">
<header className="App-header">
{store.filterredValue.map((name) => <li key={name}>{name}</li>)}
<input
onChange={(e) => this.setName(e)}
/>
</header>
</div>
);
}
}
export default App;
Svar #1
Först och främst behöver du omsluta varje komponent som använder observable-tillstånd med observer-dekoreraren, så här:
import {observer} from 'mobx-react'
@observer
class App extends React.Component {
// ...
}
// or if you are using functional components:
const App = observer(() => {
// ...
})
Dessutom, om du använder MobX version 6 behöver du lägga till anropet makeObservable inuti klasskonstruktorn:
import {observable, action, autorun, computed, makeObservable} from 'mobx'
class TodosStore {
@observable names = ["p1", "p2", "p3"]
@observable filter = ""
constructor() {
makeObservable(this);
}
@action
get filterredValue(){
return store.names.filter(word => word.includes(this.filter))
}
}
Mer om MobX och React-integrering i dokumentationen
Svar #2
Du kan definiera saker som observable, computed och action i TodoStore med makeObservable eftersom decorators för närvarande inte föredras (decorators är för närvarande inte en ES-standard, och standardiseringsprocessen tar lång tid):
TodoStore:
import { observable, autorun, computed, makeObservable, action } from "mobx";
class TodoStore {
names = ["p1", "p2", "p3"];
filter = "";
constructor() {
makeObservable(this, {
names: observable,
filter: observable,
filterredValue: computed,
setFilter: action,
});
autorun(() => {
console.log(this.filter);
console.log(this.names);
});
}
get filterredValue() {
return this.names.filter((word) => word.includes(this.filter));
}
setFilter(filter) {
this.filter = filter;
}
}
export const todoStore = new TodoStore();
Och här är App-komponenten som använder observer (En högre ordningskomponent som gör en funktionell eller klassbaserad React-komponent omrenderad när observabler ändras):
App:
import { observer } from "mobx-react";
import { Component } from "react";
class App extends Component<any> {
setName = (e: React.ChangeEvent<HTMLInputElement>) => {
this.props.store.setFilter(e.target.value);
};
render() {
return (
<div className="App">
<header className="App-header">
{this.props.store.filterredValue.map((name) => (
<li key={name}>{name}</li>
))}
<input onChange={(e) => this.setName(e)} />
</header>
</div>
);
}
}
export default observer(App);
Demo: