fix(runtime): check whether this is the first time render of an UnmountImplWrapper

when we are using slot's ifCondition, the slot may have
unmount traits result multiple times
This commit is contained in:
Yanzhen Yu 2022-07-19 20:11:15 +08:00
parent acbbf4eb24
commit 25787ec172

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react';
import { RuntimeTraitSchema } from '@sunmao-ui/core';
import { ImplWrapperMain } from './ImplWrapperMain';
import { useRuntimeFunctions } from './hooks/useRuntimeFunctions';
@ -11,6 +11,8 @@ export const UnmountImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperPr
const { component: c, services, slotContext } = props;
const { stateManager, registry } = services;
const { executeTrait } = useRuntimeFunctions(props);
const renderCount = useRef(0);
renderCount.current++;
const unmountTraits = useMemo(
() =>
@ -38,8 +40,19 @@ export const UnmountImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperPr
if (result.unmount) {
// Every component's state is initialized in initStateAnd Method.
// So if if it should not render, we should remove it from store.
// Only clear the store when the component is not hidden before this check.
if (!prevIsHidden) {
/**
* prevIsHidden: Only clear the store when the component is not
* hidden before this check.
*
* renderCount: Currently we call initStateAndMethod to setup the
* state store, and let here to teardown the hidden components'
* state. If a component is hidden forever, it still need to teardown
* at the first time it rendered.
* Not a perfect solution, and we should have better lifecycle
* management for the state store.
*/
if (!prevIsHidden || renderCount.current === 1) {
delete stateManager.store[c.id];
}
}