【发布时间】:2019-04-02 16:54:23
【问题描述】:
我见过的将 React 组件与 MobX 存储集成的示例似乎是紧密耦合的。我想以一种更可重用的方式执行此操作,并希望能帮助理解执行此操作的“正确”方式。
我编写了以下代码(React + MobX + Typescript)来说明我想要做什么以及我遇到的问题。
商店有多个可观察的时间戳。
/***
* Initialize simple store
*/
class MyStore {
@observable value: number;
@action setValue(val: number) { this.value = val; }
@observable startTimestamp: number;
@action setStartTimestamp(val: number) { this.startTimestamp = val; }
@observable endTimestamp: number;
@action setEndTimestamp(val: number) { this.endTimestamp = val; }
}
假设我想制作一个可重用的日期输入组件,允许用户为 startTimestamp、endTimestamp 或其他一些存储属性输入日期。更一般地说,我想创建一个可以用来修改任何商店的任意属性的组件。
我对 React/MobX 集成的最佳理解是组件接收 MobX 存储,读取存储的可观察属性,并可以执行操作来修改这些属性。但是,这似乎假设组件与商店属性的名称相关联,这使得它们不能完全重用。
我已经尝试了以下“代理存储”方法来将我想要的属性作为“值”公开给组件:
class MyStoreTimestampProxy {
constructor(private store: MyStore, private propertyName: 'startTimestamp' | 'endTimestamp') {
}
@observable get value() {
return this.store[this.propertyName];
}
@action setValue(val: number) {
this.store[this.propertyName] = val;
}
};
const myStoreStartTimestamp = new MyStoreTimestampProxy(myStore, 'startTimestamp');
const myStoreEndTimestamp = new MyStoreTimestampProxy(myStore, 'endTimestamp');
但是,我觉得我并没有以某种方式以 React/MobX 方式做事,并且想了解这里的最佳实践。谢谢!
完整代码如下:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { observable, action } from 'mobx';
import { observer } from 'mobx-react';
/***
* Initialize simple store
*/
class MyStore {
@observable value: number;
@action setValue(val: number) { this.value = val; }
@observable startTimestamp: number;
@action setStartTimestamp(val: number) { this.startTimestamp = val; }
@observable endTimestamp: number;
@action setEndTimestamp(val: number) { this.endTimestamp = val; }
}
const myStore = new MyStore();
myStore.setValue(new Date().getTime());
/**
* My time input component. Takes in a label for display, and a store for reading/writing the property.
*/
interface IDateInputProps {
label: string;
store: {
value: number;
setValue(val: number): void;
}
}
interface IDateInputState {
value: string;
}
@observer class DateInput extends React.Component<IDateInputProps, IDateInputState> {
constructor(props: IDateInputProps) {
super(props);
this.state = { value: new Date(props.store.value).toDateString() };
}
render() {
return (
<div>
<label>{this.props.label}
<input
value={this.state.value}
onChange={this.onChange.bind(this)} />
</label>
</div>
);
}
onChange(event) {
const date = new Date(event.target.value);
this.setState({ value: event.target.value });
this.props.store.setValue(date.getTime());
}
}
/**
* Test view
*
*/
class TestView extends React.Component {
render() {
return (
<div>
<DateInput label="Editing the value property of store: " store={myStore}></DateInput>
{/* How to create components for startTimestamp and endTimestamp */}
</div>
);
}
};
ReactDOM.render(<TestView />, document.getElementById('root'));
【问题讨论】:
标签: reactjs typescript mobx