MobX 在推送到数组时不更新 React 视图
MobX not updating React view when pushing to an array
我的Store.js:
import { observable, useStrict, action } from 'mobx';
useStrict(true);
export const state = observable({
contacts: []
});
export const actions = {
addContact: action((firstName, lastName) => {
state.contacts.push({
id: Math.floor((Math.random() * 1000) + 1),
firstName: firstName,
lastName: lastName
});
})
};
我的index.js:
import React from 'react';
import { Provider } from 'mobx-react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { state, actions } from './Store';
ReactDOM.render(
<Provider state={state} actions={actions}>
<App />
</Provider>,
document.getElementById('root')
);
registerServiceWorker();
我的App.js:
import React, { Component } from 'react';
import ContactList from './components/ContactList';
import ContactAdder from './components/ContactAdder';
import { observer, inject } from 'mobx-react';
const App = inject('state', 'actions')(observer(class App extends Component {
render() {
return (
<div>
<h1>Contacts</h1>
<ContactList
contacts={this.props.state.contacts}
onDelete={this.props.actions.removeContact}
/>
<ContactAdder onAdd={this.props.actions.addContact} />
</div>
);
}
}));
export default App;
最后是我的 ContactAdder.js:
import React, { Component } from 'react';
class ContactAdder extends Component {
render() {
return (
<div className='ContactAdder'>
<input type='text' value='' placeholder='First Name' />
<input type='text' value='' placeholder='Last Name' />
<button onClick={this.props.onAdd.bind(this, 'Test', 'Testerson')}>Add</button>
</div>
);
}
}
export default ContactAdder;
addContact()
在 Store.js
中运行后,我可以看到,当我执行控制台日志时,数组确实发生了变化。但出于某种原因,我的观点没有反应。我做错了什么?
在没有看到您的 ContactList
组件的情况下,我认为如果您也将其制作成 observer
,问题就会得到解决。
一旦在先前渲染中取消引用的可观察对象发生更改,观察者组件将重新渲染。 this.props.state.contacts
不会取消引用您的联系人数组。如果你写 this.props.state.contacts.slice()
或 this.props.state.contacts.peek()
,它会起作用,但通常只在 passing observables to external libraries 时使用。
您最好让所有使用可观察对象的组件 observers
尽可能高效。
<ContactList
contacts={this.props.state.contacts.toJS()}
onDelete={this.props.actions.removeContact}
/>
尝试使用 toJS()
方法 state.contacts
将 ObservableArray 转换为 Array,然后它会更新 ContactList。
我的Store.js:
import { observable, useStrict, action } from 'mobx';
useStrict(true);
export const state = observable({
contacts: []
});
export const actions = {
addContact: action((firstName, lastName) => {
state.contacts.push({
id: Math.floor((Math.random() * 1000) + 1),
firstName: firstName,
lastName: lastName
});
})
};
我的index.js:
import React from 'react';
import { Provider } from 'mobx-react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { state, actions } from './Store';
ReactDOM.render(
<Provider state={state} actions={actions}>
<App />
</Provider>,
document.getElementById('root')
);
registerServiceWorker();
我的App.js:
import React, { Component } from 'react';
import ContactList from './components/ContactList';
import ContactAdder from './components/ContactAdder';
import { observer, inject } from 'mobx-react';
const App = inject('state', 'actions')(observer(class App extends Component {
render() {
return (
<div>
<h1>Contacts</h1>
<ContactList
contacts={this.props.state.contacts}
onDelete={this.props.actions.removeContact}
/>
<ContactAdder onAdd={this.props.actions.addContact} />
</div>
);
}
}));
export default App;
最后是我的 ContactAdder.js:
import React, { Component } from 'react';
class ContactAdder extends Component {
render() {
return (
<div className='ContactAdder'>
<input type='text' value='' placeholder='First Name' />
<input type='text' value='' placeholder='Last Name' />
<button onClick={this.props.onAdd.bind(this, 'Test', 'Testerson')}>Add</button>
</div>
);
}
}
export default ContactAdder;
addContact()
在 Store.js
中运行后,我可以看到,当我执行控制台日志时,数组确实发生了变化。但出于某种原因,我的观点没有反应。我做错了什么?
在没有看到您的 ContactList
组件的情况下,我认为如果您也将其制作成 observer
,问题就会得到解决。
一旦在先前渲染中取消引用的可观察对象发生更改,观察者组件将重新渲染。 this.props.state.contacts
不会取消引用您的联系人数组。如果你写 this.props.state.contacts.slice()
或 this.props.state.contacts.peek()
,它会起作用,但通常只在 passing observables to external libraries 时使用。
您最好让所有使用可观察对象的组件 observers
尽可能高效。
<ContactList
contacts={this.props.state.contacts.toJS()}
onDelete={this.props.actions.removeContact}
/>
尝试使用 toJS()
方法 state.contacts
将 ObservableArray 转换为 Array,然后它会更新 ContactList。