Skip to content

Commit

Permalink
fix: switch page error
Browse files Browse the repository at this point in the history
  • Loading branch information
ShenChang618 committed May 15, 2019
1 parent 820c6a7 commit 11e9f40
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 23 deletions.
2 changes: 1 addition & 1 deletion demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function App() {
<Route
path="/b"
render={() => (
<KeepAlive name="A"><B /></KeepAlive>
<KeepAlive name="A"><B /><B /></KeepAlive>

)}
/>
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"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.",
"author": "Shen Chang",
"homepage": "https://github.com/Sam618/react-keep-alive",
Expand Down Expand Up @@ -37,8 +37,7 @@
"dependencies": {
"@types/js-md5": "^0.4.2",
"hoist-non-react-statics": "^3.3.0",
"js-md5": "^0.7.3",
"react-deep-force-update": "^2.1.3"
"js-md5": "^0.7.3"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
Expand Down
43 changes: 37 additions & 6 deletions src/components/AsyncComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react';
import deepForceUpdate from 'react-deep-force-update';
import {bindLifecycleTypeName} from '../utils/bindLifecycle';

interface IProps {
setMounted: any;
getMounted: any;
correctionPosition: any;
setMounted: (value: boolean) => void;
getMounted: () => boolean;
onUpdate: () => void;
}

interface IState {
Expand All @@ -16,13 +16,44 @@ export default class AsyncComponent extends React.Component<IProps, IState> {
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() {
const {children} = this.props;
Promise.resolve().then(() => this.setState({component: children}));
}

public componentDidUpdate() {
this.props.correctionPosition();
this.props.onUpdate();
}

// Delayed update
Expand All @@ -36,7 +67,7 @@ export default class AsyncComponent extends React.Component<IProps, IState> {
Promise.resolve().then(() => {
if (this.props.getMounted()) {
this.props.setMounted(false);
deepForceUpdate(this);
this.forceUpdateChildren();
}
});
return false;
Expand Down
6 changes: 4 additions & 2 deletions src/components/KeepAlive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ class KeepAlive extends React.PureComponent<IKeepAliveInnerProps> {
if (this.ref && this.ref.parentNode && this.ref.nextSibling) {
const childNodes = this.ref.childNodes as any;
this.refNextSibling = this.ref.nextSibling;
for (const child of childNodes) {
this.childNodes = [];
while (childNodes.length) {
const child = childNodes[0];
this.childNodes.push(child);
this.ref.parentNode.insertBefore(child, this.ref.nextSibling);
}
Expand Down Expand Up @@ -183,7 +185,7 @@ class KeepAlive extends React.PureComponent<IKeepAliveInnerProps> {
<AsyncComponent
setMounted={this.setMounted}
getMounted={this.getMounted}
correctionPosition={this.correctionPosition}
onUpdate={this.correctionPosition}
>
{this.props.children}
</AsyncComponent>
Expand Down
7 changes: 0 additions & 7 deletions src/components/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import ReactDOM from 'react-dom';
import Comment from './Comment';
import KeepAliveContext from '../contexts/KeepAliveContext';
import createEventEmitter from '../utils/createEventEmitter';
import {warn} from '../utils/debug';
import createUniqueIdentification from '../utils/createUniqueIdentification';
import createStoreElement from '../utils/createStoreElement';

Expand Down Expand Up @@ -94,12 +93,6 @@ export default class KeepAliveProvider extends React.PureComponent<IKeepAlivePro
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) => {
const {cache} = this;
this.cache[identification] = {
Expand Down
5 changes: 4 additions & 1 deletion src/utils/bindLifecycle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {COMMAND} from './keepAliveDecorator';
import withIdentificationContextConsumer from './withIdentificationContextConsumer';
import getDisplayName from './getDisplayName';

export const bindLifecycleTypeName = '$$bindLifecycle';

export default function bindLifecycle<P = any>(Component: React.ComponentClass<P>) {
const WrappedComponent = (Component as any).WrappedComponent || (Component as any).wrappedComponent || Component;

Expand Down Expand Up @@ -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.
WrappedComponent.prototype.shouldComponentUpdate = function (...args: any) {
if (this._needActivate) {
this.forceUpdate();
return false;
}
return shouldComponentUpdate.call(this, ...args) || true;
Expand Down Expand Up @@ -129,7 +132,7 @@ export default function bindLifecycle<P = any>(Component: React.ComponentClass<P
));

(BindLifecycle as any).WrappedComponent = WrappedComponent;
BindLifecycle.displayName = `bindLifecycle(${getDisplayName(Component)})`;
BindLifecycle.displayName = `${bindLifecycleTypeName}(${getDisplayName(Component)})`;
return hoistNonReactStatics(
BindLifecycle,
Component,
Expand Down
3 changes: 0 additions & 3 deletions typings/react-deep-force-update.d.ts

This file was deleted.

0 comments on commit 11e9f40

Please sign in to comment.