【发布时间】:2018-07-11 00:24:18
【问题描述】:
我正在尝试让 MobX 在反应中使用功能组件。我想这样做而不必使用装饰器。我已经使用 create-react-app 设置了一个应用程序,添加了 MobX 和 MobX-react 作为依赖项。 但是,我似乎无法让 observables 在功能组件中工作。
import React from 'react';
import { extendObservable } from 'mobx';
import { observer } from 'mobx-react';
const Test = () => {
extendObservable(this, {
button: false
});
const handleB1 = () => {
this.button = false;
}
const handleB2 = () => {
this.button = true;
}
const getButton2 = () => {
console.log('button2');
return (
<button type="button" onClick={handleB2}>Button 2</button>
);
};
const getButton1 = () => {
console.log('button1');
return (
<button type="button" onClick={handleB1}>Button 1</button>
);
};
return (
<div>
{this.button ? getButton1() : getButton2()}
</div>
)
};
export default observer(Test);
单击按钮,我希望组件由于 observable 被更改而重新渲染,但我收到一个错误:
×
Error: [mobx] Invariant failed: Side effects like changing state are not
allowed at this point. Are you trying to modify state from, for example, the render
function of a React component? Tried to modify: ObservableObject@2.button
我曾尝试将可观察对象声明为功能组件的一部分,或者像这样声明:
const buttonState = () => {
extendObservable(this, {
button: false
});
}
但在这两种情况下,我都无法让组件重新渲染,或者我不确定 observable 是否实际设置正确。
如果我把整个东西写成这样的一个类,它就可以完美地工作
import React from 'react';
import { extendObservable } from 'mobx';
import { observer } from 'mobx-react';
class Test extends React.Component {
constructor(props) {
super();
extendObservable(this, {
button: false
});
}
handleB1 = () => {
this.button = false;
}
handleB2 = () => {
this.button = true;
}
getButton2 = () => {
console.log('button2');
return (
<button type="button" onClick={this.handleB2}>Button 2</button>
);
};
getButton1 = () => {
console.log('button1');
return (
<button type="button" onClick={this.handleB1}>Button 1</button>
);
};
render = () => {
return (
<div>
{this.button ? this.getButton1() : this.getButton2()}
</div>
)
}
};
export default observer(Test);
【问题讨论】:
-
功能组件只是一个功能,因此
extendObservable(this, ... )不会像类示例中那样工作。如果有状态,为什么要使用函数式组件? -
好吧,我想使用函数式组件,因为我发现语法更易于阅读。最初我是为一个简单的删除按钮编写的,单击后会展开以显示两个按钮,一个用于确认,一个用于删除。我认为在像这样的简单组件中包含一个状态是有道理的,但现在你已经为我解释清楚了,现在它实际上是有道理的。
-
虽然,再次查看文档后,这部分似乎是我想做的:mobx.js.org/best/…
-
如果你有一个
Timer对象,那会很好用,但如果它是一个 ReactTimerView,恐怕它不会按预期工作。
标签: reactjs mobx mobx-react