Skip to content

Commit

Permalink
feat: rerender props (#610) (#666)
Browse files Browse the repository at this point in the history
* Feat/rerender props (#610)

* log: props更新后重新渲染微模块

* log: 修改文档 && 补充 render 场景下的单元测试

Co-authored-by: huhaojie <huhaojie.hhj@alibaba-inc.com>

* fix: test case

---------

Co-authored-by: HuColin <colin1501@outlook.com>
Co-authored-by: huhaojie <huhaojie.hhj@alibaba-inc.com>
  • Loading branch information
3 people authored Jan 18, 2024
1 parent afb4e2b commit 53185b2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
39 changes: 36 additions & 3 deletions packages/icestark-module/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
unmoutModule,
removeCSS,
registerModule,
registerModules,
} from '../src/modules';
import MicroModule, { renderModules, renderComponent } from '../src/MicroModule';

Expand All @@ -33,6 +32,23 @@ const defaultUnmount = (targetNode: HTMLElement) => {
ReactDOM.unmountComponentAtNode(targetNode);
};

const TestModule = ({ value = 1 }: { value?: number }) => {
console.log('hhj-log', 'value', value);
return <span>{value}</span>;
};

const TestHost = ({ initialValue }: { initialValue: number }) => {
const [value, setValue] = React.useState<number>(initialValue);

React.useEffect(() => {
setTimeout(() => {
setValue((value) => value + 1);
}, 500);
}, []);

return <MicroModule moduleName="moduleA" value={value} />;
};

const modules = [{
name: 'selfComponent',
url: 'http://127.0.0.1:3334/index.js',
Expand Down Expand Up @@ -108,7 +124,7 @@ describe('render modules', () => {
expect(container.innerHTML).toBe('<div><div><h2>404</h2></div></div>');
next();
}, 0);
});
});

test('render MicroModule with custom className and style', (next) => {
const { container } = render(<MicroModule moduleName="selfComponent" wrapperClassName="test" wrapperStyle={{ fontSize: '14px' }} sandbox />);
Expand Down Expand Up @@ -183,8 +199,25 @@ describe('render modules', () => {
});
})

test('props rerender', async () => {
registerModule({
name: 'moduleA',
render: (props: any) => {
return <TestModule {...props}/>
},
});
const { container } = render(<TestHost initialValue={5} />);
expect(container.innerHTML).toBe('<div><span>5</span></div>');
await new Promise<void>((resolve) => {
setTimeout(() => {
expect(container.innerHTML).toBe('<div><span>6</span></div>');
resolve();
}, 2000);
});
});

test('clear module', () => {
clearModules();
expect(getModules()).toStrictEqual([]);
});
});
});
18 changes: 15 additions & 3 deletions packages/icestark-module/src/MicroModule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export default class MicroModule extends React.Component<any, State> {

private unmout = false;

// moduleInfo 中定义的 mount 函数
private moduleLifecycleMount = null;

// 从 moduleInfo 配置中解析得到的模块组件
private moduleComponent = null;

constructor(props) {
super(props);
this.state = {
Expand All @@ -48,9 +54,13 @@ export default class MicroModule extends React.Component<any, State> {
const { moduleInfo: preModuleInfo = {}, ...preRest } = prevProps;
const { moduleInfo: curModuleInfo = {}, ...curRest } = this.props;

if (!shallowCompare(preModuleInfo, curModuleInfo) || !shallowCompare(preRest, curRest)) {
if (!shallowCompare(preModuleInfo, curModuleInfo)) {
this.mountModule();
}
if (!shallowCompare(preRest, curRest)) {
// 对于除 moduleInfo 外的 props 更新,重新渲染模块
this.moduleLifecycleMount && this.moduleLifecycleMount(this.moduleComponent, this.mountNode, curRest);
}
}

componentWillUnmount() {
Expand Down Expand Up @@ -95,6 +105,8 @@ export default class MicroModule extends React.Component<any, State> {
try {
const { mount, component } = await loadModule(this.moduleInfo, this.props.sandbox);
const lifecycleMount = mount;
this.moduleLifecycleMount = mount;
this.moduleComponent = component;

!this.unmout && this.setState({ loading: false });
if (lifecycleMount && component) {
Expand Down Expand Up @@ -122,7 +134,7 @@ export default class MicroModule extends React.Component<any, State> {
const { loading } = this.state;
const { render } = this.moduleInfo || {};

const { wrapperClassName, wrapperStyle, loadingComponent } = this.props;
const { wrapperClassName, wrapperStyle, loadingComponent, ...restProps } = this.props;
return loading
? loadingComponent
: (
Expand All @@ -131,7 +143,7 @@ export default class MicroModule extends React.Component<any, State> {
style={wrapperStyle}
ref={(ref) => { this.mountNode = ref; }}
>
{ this.moduleInfo && this.validateRender() && render() }
{ this.moduleInfo && this.validateRender() && render(restProps) }
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion website/docs/guide/micro-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ import LocalComponent from './localComponent';

registerModules([{
name: 'moduleName',
render: () => LocalComponent,
render: (props) => <LocalComponent {...props} />,
}]);

const App = () => {
Expand Down

0 comments on commit 53185b2

Please sign in to comment.