要求是:
切换以打开行组件
使用青色
的背景颜色突出显示所选行
但是,当我点击切换按钮时,App组件不会被重新渲染:(
// App.js
import React, { Component } from 'react';
import {observable, action } from 'mobx';
import {observer} from 'mobx-react';
@observer class Rows extends Component {
rows() {
let { store } = this.props;
var rows = [];
for (var i = 4; i > 0; i--) {
rows.push(
<div
style={i == store.selectedRow ? { backgroundColor: "cyan" } : null }
onClick={store.selectRow.bind(this, i)}>
{ i }
</div>
)
}
return rows;
}
render() {
return (<div>{this.rows()}</div>);
}
}
class Store {
constructor(props) {
this.selectRow = this.selectRow.bind(this)
this.toggleSelector = this.toggleSelector.bind(this)
}
@observable showSelector = false;
@observable selectedRow = 4;
@action selectRow(n) {
this.selectedVersion = n;
}
@action toggleSelector() {
this.showSelector = !this.showSelector;
}
}
//edit here
const store = new Store();
@observer class App extends Component {
render() {
return (
<div className="App">
<button onClick={store.toggleSelector}>Toggle Selector</button>
{ store.showSelector ? <Rows store={store}/> : null }
</div>
);
}
}
export default App;
编辑根据建议,我已经在组件外部提取了商店的创建。
答案 0 :(得分:2)
更新:您可以尝试使用@action.bound
装饰器,并在构造函数中完全跳过bind(this)
。我的猜测是手动绑定会破坏绑定(没有双关语)。
请参阅action.bound
动作装饰器/函数遵循javascript中绑定的常规规则。但是,Mobx 3引入了action.bound以自动将操作绑定到目标对象。请注意,与action不同,(@)action.bound不接受name参数,因此名称将始终基于绑定操作的属性名称。
您的商店未被观察,因为它是在 render()
内创建的。您需要创建商店并通过props
或MobX的Provider将其传递给您的组件。
Provider是一个可以使用React的上下文机制将存储(或其他东西)传递给子组件的组件。如果你有一些不想明确地通过多层组件的东西,那么这很有用。
注入可以用来拿起那些商店。它是一个更高阶的组件,它接受一个字符串列表并使这些存储可用于包装组件。
答案 1 :(得分:0)
试试这个。
// App.js
import React, { Component } from 'react';
import {observable, action } from 'mobx';
import {observer} from 'mobx-react';
@observer class Rows extends Component {
rows() {
let { store } = this.props;
var rows = [];
for (var i = 4; i > 0; i--) {
rows.push(
<div
style={i == store.selectedRow ? { backgroundColor: "cyan" } : null }
onClick={store.selectRow.bind(this, i)}>
{ i }
</div>
)
}
return rows;
}
render() {
return (<div>{this.rows()}</div>);
}
}
class Store {
constructor(props) {
this.selectRow = this.selectRow.bind(this)
this.toggleSelector = this.toggleSelector.bind(this)
}
@observable showSelector = false;
@observable selectedRow = 4;
@action selectRow(n) {
this.selectedVersion = n;
}
@action toggleSelector() {
this.toggleSelector = !this.showSelector;
}
}
// defined outside
const store = new Store();
@observer class App extends Component {
render() {
return (
<div className="App">
<button onClick={store.toggleSelector}>Toggle Selector</button>
{ store.showSelector ? <Rows store={store}/> : null }
</div>
);
}
}
export default App;