Skip to content

Commit 4b9582a

Browse files
committed
feat: extract react service, and re render by observable model
1 parent 85eed7e commit 4b9582a

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

src/services/react/component.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { BaseService } from 'mo/services/baseService';
2+
3+
export abstract class Component<S> extends BaseService {
4+
protected abstract state: S;
5+
6+
public updateState(nextState: S) {
7+
Object.assign(this.state, nextState);
8+
}
9+
10+
public getState(): S {
11+
return this.state;
12+
}
13+
}

src/services/react/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './component';
2+
export * from './mapState';

src/services/react/mapState.tsx

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as React from 'react';
2+
import Logger from 'mo/common/logger';
3+
4+
/**
5+
* Mapping the state to the component
6+
* @param WrappedComponent The component will be wrapped
7+
* @param state The state you want to injected, notice the state must be an observable object
8+
* @param subscribes The events of your subscribe, it used to trigger the state re render
9+
*/
10+
export function mapState<S>(WrappedComponent: React.ComponentType<S>, state: S) {
11+
return class StateProvider extends React.Component {
12+
state: { lastUpdated: number };
13+
constructor(props) {
14+
super(props);
15+
this.onChange = this.onChange.bind(this);
16+
this.state = {
17+
lastUpdated: Date.now(),
18+
};
19+
}
20+
21+
_count = 0;
22+
23+
componentDidMount() {
24+
// There is no declare state argument as IObservable type, so must convert to any type.
25+
if ((state as any).observe) {
26+
console.log('mapState:', this._count++);
27+
(state as any).observe(this.onChange);
28+
} else {
29+
Logger.error('The state argument of mapState must be an observable object.');
30+
}
31+
}
32+
/**
33+
* TODO: Performance optimize, now whatever any properties changed in target,
34+
* there always be trigger the onChange event, so need a compare operation.
35+
* @param nextState changed data
36+
*/
37+
onChange(nextState: S) {
38+
Logger.info(nextState, state);
39+
this.setState({
40+
lastUpdated: Date.now(),
41+
});
42+
}
43+
44+
render() {
45+
return (
46+
<WrappedComponent {...this.state} { ...state} {...this.props} />
47+
);
48+
}
49+
};
50+
}

0 commit comments

Comments
 (0)