Skip to content

Commit

Permalink
feat: extract react service, and re render by observable model
Browse files Browse the repository at this point in the history
  • Loading branch information
wewoor committed Oct 31, 2020
1 parent 85eed7e commit 4b9582a
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/services/react/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { BaseService } from 'mo/services/baseService';

export abstract class Component<S> extends BaseService {
protected abstract state: S;

public updateState(nextState: S) {
Object.assign(this.state, nextState);
}

public getState(): S {
return this.state;
}
}
2 changes: 2 additions & 0 deletions src/services/react/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './component';
export * from './mapState';
50 changes: 50 additions & 0 deletions src/services/react/mapState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as React from 'react';
import Logger from 'mo/common/logger';

/**
* Mapping the state to the component
* @param WrappedComponent The component will be wrapped
* @param state The state you want to injected, notice the state must be an observable object
* @param subscribes The events of your subscribe, it used to trigger the state re render
*/
export function mapState<S>(WrappedComponent: React.ComponentType<S>, state: S) {
return class StateProvider extends React.Component {
state: { lastUpdated: number };
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.state = {
lastUpdated: Date.now(),
};
}

_count = 0;

componentDidMount() {
// There is no declare state argument as IObservable type, so must convert to any type.
if ((state as any).observe) {
console.log('mapState:', this._count++);
(state as any).observe(this.onChange);
} else {
Logger.error('The state argument of mapState must be an observable object.');
}
}
/**
* TODO: Performance optimize, now whatever any properties changed in target,
* there always be trigger the onChange event, so need a compare operation.
* @param nextState changed data
*/
onChange(nextState: S) {
Logger.info(nextState, state);
this.setState({
lastUpdated: Date.now(),
});
}

render() {
return (
<WrappedComponent {...this.state} { ...state} {...this.props} />
);
}
};
}

0 comments on commit 4b9582a

Please sign in to comment.