Commit 11e9f40b authored by Shen Chang's avatar Shen Chang

fix: switch page error

parent 820c6a77
...@@ -43,7 +43,7 @@ function App() { ...@@ -43,7 +43,7 @@ function App() {
<Route <Route
path="/b" path="/b"
render={() => ( render={() => (
<KeepAlive name="A"><B /></KeepAlive> <KeepAlive name="A"><B /><B /></KeepAlive>
)} )}
/> />
......
{ {
"name": "react-keep-alive", "name": "react-keep-alive",
"version": "2.0.0", "version": "2.0.1",
"description": "Package will allow components to maintain their status, to avoid repeated re-rendering.", "description": "Package will allow components to maintain their status, to avoid repeated re-rendering.",
"author": "Shen Chang", "author": "Shen Chang",
"homepage": "https://github.com/Sam618/react-keep-alive", "homepage": "https://github.com/Sam618/react-keep-alive",
...@@ -37,8 +37,7 @@ ...@@ -37,8 +37,7 @@
"dependencies": { "dependencies": {
"@types/js-md5": "^0.4.2", "@types/js-md5": "^0.4.2",
"hoist-non-react-statics": "^3.3.0", "hoist-non-react-statics": "^3.3.0",
"js-md5": "^0.7.3", "js-md5": "^0.7.3"
"react-deep-force-update": "^2.1.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.2.3", "@babel/cli": "^7.2.3",
......
import * as React from 'react'; import * as React from 'react';
import deepForceUpdate from 'react-deep-force-update'; import {bindLifecycleTypeName} from '../utils/bindLifecycle';
interface IProps { interface IProps {
setMounted: any; setMounted: (value: boolean) => void;
getMounted: any; getMounted: () => boolean;
correctionPosition: any; onUpdate: () => void;
} }
interface IState { interface IState {
...@@ -16,13 +16,44 @@ export default class AsyncComponent extends React.Component<IProps, IState> { ...@@ -16,13 +16,44 @@ export default class AsyncComponent extends React.Component<IProps, IState> {
component: null, component: null,
}; };
/**
* Force update child nodes
*
* @private
* @returns
* @memberof AsyncComponent
*/
private forceUpdateChildren() {
if (!this.props.children) {
return;
}
const root: any = (this as any)._reactInternalFiber || (this as any)._reactInternalInstance;
let node = root.child;
let sibling = node;
while (sibling) {
while (true) {
if (node.type && node.type.displayName && node.type.displayName.indexOf(bindLifecycleTypeName) !== -1) {
return;
}
if (node.stateNode) {
break;
}
node = node.child;
}
if (typeof node.type === 'function') {
node.stateNode.forceUpdate();
}
sibling = sibling.sibling;
}
}
public componentDidMount() { public componentDidMount() {
const {children} = this.props; const {children} = this.props;
Promise.resolve().then(() => this.setState({component: children})); Promise.resolve().then(() => this.setState({component: children}));
} }
public componentDidUpdate() { public componentDidUpdate() {
this.props.correctionPosition(); this.props.onUpdate();
} }
// Delayed update // Delayed update
...@@ -36,7 +67,7 @@ export default class AsyncComponent extends React.Component<IProps, IState> { ...@@ -36,7 +67,7 @@ export default class AsyncComponent extends React.Component<IProps, IState> {
Promise.resolve().then(() => { Promise.resolve().then(() => {
if (this.props.getMounted()) { if (this.props.getMounted()) {
this.props.setMounted(false); this.props.setMounted(false);
deepForceUpdate(this); this.forceUpdateChildren();
} }
}); });
return false; return false;
......
...@@ -104,7 +104,9 @@ class KeepAlive extends React.PureComponent<IKeepAliveInnerProps> { ...@@ -104,7 +104,9 @@ class KeepAlive extends React.PureComponent<IKeepAliveInnerProps> {
if (this.ref && this.ref.parentNode && this.ref.nextSibling) { if (this.ref && this.ref.parentNode && this.ref.nextSibling) {
const childNodes = this.ref.childNodes as any; const childNodes = this.ref.childNodes as any;
this.refNextSibling = this.ref.nextSibling; this.refNextSibling = this.ref.nextSibling;
for (const child of childNodes) { this.childNodes = [];
while (childNodes.length) {
const child = childNodes[0];
this.childNodes.push(child); this.childNodes.push(child);
this.ref.parentNode.insertBefore(child, this.ref.nextSibling); this.ref.parentNode.insertBefore(child, this.ref.nextSibling);
} }
...@@ -183,7 +185,7 @@ class KeepAlive extends React.PureComponent<IKeepAliveInnerProps> { ...@@ -183,7 +185,7 @@ class KeepAlive extends React.PureComponent<IKeepAliveInnerProps> {
<AsyncComponent <AsyncComponent
setMounted={this.setMounted} setMounted={this.setMounted}
getMounted={this.getMounted} getMounted={this.getMounted}
correctionPosition={this.correctionPosition} onUpdate={this.correctionPosition}
> >
{this.props.children} {this.props.children}
</AsyncComponent> </AsyncComponent>
......
...@@ -3,7 +3,6 @@ import ReactDOM from 'react-dom'; ...@@ -3,7 +3,6 @@ import ReactDOM from 'react-dom';
import Comment from './Comment'; import Comment from './Comment';
import KeepAliveContext from '../contexts/KeepAliveContext'; import KeepAliveContext from '../contexts/KeepAliveContext';
import createEventEmitter from '../utils/createEventEmitter'; import createEventEmitter from '../utils/createEventEmitter';
import {warn} from '../utils/debug';
import createUniqueIdentification from '../utils/createUniqueIdentification'; import createUniqueIdentification from '../utils/createUniqueIdentification';
import createStoreElement from '../utils/createStoreElement'; import createStoreElement from '../utils/createStoreElement';
...@@ -94,12 +93,6 @@ export default class KeepAliveProvider extends React.PureComponent<IKeepAlivePro ...@@ -94,12 +93,6 @@ export default class KeepAliveProvider extends React.PureComponent<IKeepAlivePro
this.forceUpdate(); this.forceUpdate();
} }
public componentDidCatch(_: any, info: any) {
if (info.componentStack.indexOf(keepAliveProviderTypeName) !== -1) {
warn('[React Keep Alive] Cached components have duplicates. Please check the <KeepAlive> component of the key duplication!');
}
}
public unactivate = (identification: string) => { public unactivate = (identification: string) => {
const {cache} = this; const {cache} = this;
this.cache[identification] = { this.cache[identification] = {
......
...@@ -6,6 +6,8 @@ import {COMMAND} from './keepAliveDecorator'; ...@@ -6,6 +6,8 @@ import {COMMAND} from './keepAliveDecorator';
import withIdentificationContextConsumer from './withIdentificationContextConsumer'; import withIdentificationContextConsumer from './withIdentificationContextConsumer';
import getDisplayName from './getDisplayName'; import getDisplayName from './getDisplayName';
export const bindLifecycleTypeName = '$$bindLifecycle';
export default function bindLifecycle<P = any>(Component: React.ComponentClass<P>) { export default function bindLifecycle<P = any>(Component: React.ComponentClass<P>) {
const WrappedComponent = (Component as any).WrappedComponent || (Component as any).wrappedComponent || Component; const WrappedComponent = (Component as any).WrappedComponent || (Component as any).wrappedComponent || Component;
...@@ -59,6 +61,7 @@ export default function bindLifecycle<P = any>(Component: React.ComponentClass<P ...@@ -59,6 +61,7 @@ export default function bindLifecycle<P = any>(Component: React.ComponentClass<P
// In order to be able to re-update after transferring the DOM, we need to block the first update. // In order to be able to re-update after transferring the DOM, we need to block the first update.
WrappedComponent.prototype.shouldComponentUpdate = function (...args: any) { WrappedComponent.prototype.shouldComponentUpdate = function (...args: any) {
if (this._needActivate) { if (this._needActivate) {
this.forceUpdate();
return false; return false;
} }
return shouldComponentUpdate.call(this, ...args) || true; return shouldComponentUpdate.call(this, ...args) || true;
...@@ -129,7 +132,7 @@ export default function bindLifecycle<P = any>(Component: React.ComponentClass<P ...@@ -129,7 +132,7 @@ export default function bindLifecycle<P = any>(Component: React.ComponentClass<P
)); ));
(BindLifecycle as any).WrappedComponent = WrappedComponent; (BindLifecycle as any).WrappedComponent = WrappedComponent;
BindLifecycle.displayName = `bindLifecycle(${getDisplayName(Component)})`; BindLifecycle.displayName = `${bindLifecycleTypeName}(${getDisplayName(Component)})`;
return hoistNonReactStatics( return hoistNonReactStatics(
BindLifecycle, BindLifecycle,
Component, Component,
......
declare module "react-deep-force-update" {
export default function deepForceUpdate(instance: any, shouldUpdate?: Function, onUpdate?: Function): void;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment