Giter VIP home page Giter VIP logo

react-keep-alive's People

Contributors

shenchang618 avatar xcqwan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-keep-alive's Issues

未能从内嵌自定义的 Context 中使用 Consumer 读取数据

Hello

由于 react-keep-alive 原理大致为将 KeepAlive children 提取出来渲染到 <KeepAliveProvider /> 节点下,而非 <KeepAlive />之下

这将导致 KeepAlive 中的组件无法被 React 认为是在其所处的上下文之中

样例大致如下:

https://codesandbox.io/s/basic-currently-rwo9y

import React, { createContext, useState } from "react";
import ReactDOM from "react-dom";
import { Provider as KeepAliveProvider, KeepAlive } from "react-keep-alive";

const { Provider, Consumer } = createContext();

function Test({ contextValue = null }) {
  return (
    <div>
      <p>contextValue: {contextValue}</p>
    </div>
  );
}

function App() {
  const [show, setShow] = useState(true);
  const toggle = () => setShow(show => !show);
  return (
    <KeepAliveProvider>
      <div>
        <Provider value={1}>
          {show && (
            <KeepAlive name="Test">
                <Consumer>
                  {context => <Test contextValue={context} />}
                </Consumer>
            </KeepAlive>
          )}
          <button onClick={toggle}>toggle</button>
        </Provider>
      </div>
    </KeepAliveProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

样例中的 <Test /> 无法从 <Consumer /> 中获得 contextValue 属性

从实现原理上来说目前似乎无法避免,是不得已而为之

想问问在这方面有没有考虑其他可能的实现方式呢?

目前会对直觉上的 Context 造成破坏,有不小的危害性,如果目前无法修复的话,个人认为有必要在 README 中给出警示

未能保留组件中滚动容器的滚动位置

测试时发现这个情况

使用 <KeepAlive /> 包裹长列表组件后,列表滚动至底部并触发 keep-alive,缓存恢复时,长列表的 scrollTop 恢复为 0

猜测和 createPortal 工作方式有关,或者是不是我的使用方式有误?

经过滚动条页面后,发现有bug

用了antd样式,然后发现为什么缓存了之后,只要选择了有滚动条的页面,然后进入其他页面,发现底部有空白区,这怎么解决?

限制keep alive数量

考虑到keep alive的组件不会被回收,将常驻内存,如果用户长时间使用,势必会存在占用大量内存。因此希望可以有办法限制alive组件数量。
尝试过动态修改provider的include,不过不生效。建议可以在include值变化后,清理不符合include规则的alive组件移除。
@Sam618 麻烦看下有没有什么办法解决,实际工程中应用比较迫切需要解决的问题

期望添加服务端渲支持

我在next.js 上使用报错 document is not defined

ReferenceError: document is not defined
at Object.createStoreElement [as default] (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_react-keep-alive@2.1.0@react-keep-alive/cjs/utils/createStoreElement.js:5:24)
at new KeepAliveProvider (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_react-keep-alive@2.1.0@react-keep-alive/cjs/components/Provider.js:49:58)
at processChild (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_react-dom@16.8.6@react-dom/cjs/react-dom-server.node.development.js:2846:14)
at resolve (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_react-dom@16.8.6@react-dom/cjs/react-dom-server.node.development.js:2812:5)
at ReactDOMServerRenderer.render (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_react-dom@16.8.6@react-dom/cjs/react-dom-server.node.development.js:3202:22)
at ReactDOMServerRenderer.read (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_react-dom@16.8.6@react-dom/cjs/react-dom-server.node.development.js:3161:29)
at renderToString (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_react-dom@16.8.6@react-dom/cjs/react-dom-server.node.development.js:3646:27)
at render (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_next-server@8.1.0@next-server/dist/server/render.js:86:16)
at renderPage (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_next-server@8.1.0@next-server/dist/server/render.js:211:20)
at Function.value (/Users/panghongye/Desktop/Project/bemular-saas-website/.next/server/static/development/pages/_document.js:555:41)
at Object.loadGetInitialProps (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_next-server@8.1.0@next-server/dist/lib/utils.js:42:35)
at Object.renderToHTML (/Users/panghongye/Desktop/Project/bemular-saas-website/node_modules/_next-server@8.1.0@next-server/dist/server/render.js:218:36)

我需要作者您的技术指导,正在阅读修改源码

我需要作者的技术指导,正在阅读修改源码,

感谢作者写出这么强大的库,但是在我的业务应用场景中(非常复杂),需要改动,所以想了解下这个库整体的架构设计思路。 替换规则,可以简要说明一下吗?我打算应用在我比较复杂的项目中。

KeepAlive包裹的组件,当中如果有state,只会渲染初始值,当state改变的时候不能更新

const [value,setValue] = useState('');
const change = (e) => {
setValue(e.target.value);
}
return (



<input onChange={(e) => { change(e) }} />


value:{value}




)
这样子的话,value只会渲染初始值,后面的不再渲染。有什么办法使得KeepAlive里面的state能实时更新。
(项目中有个情景:一个列表,数据通过useState保存,当前第一页,点击到第二页的时候,state会更新,但是列表组件放在KeepAlive 中会无法更新)

请问这个有什么好的解决办法不

[feature request]支持服务端渲染

// 目前只能这样
function useReady() {
  const [ready, setReady] = useState(false);
  useEffect(() => {
    setReady(true);
  }, []);
  return ready;
}
function Component() {
  const ready = useReady();

  const child = (......);

  const keepAlive = <KeepAlive name={...}>{child}</KeepAlive>;
  return <Provider>
      {!ready ? child : keepAlive}
   </Provider>
}

这步操作应该在内部完成:

export function KeepAlive() {
  const ready = useReady();
  return !ready ? renderImmediate() : normalRender();
}

目前服务端只能渲染空节点。

disable属性不太会用

在工作中,由详情页调到列表页,列表页需要缓存,但从修改业到列表页,列表页不需要缓存,需要动态控制,麻烦能不能给个demo,关于disable的

问下小伙伴们对于现在的生命周期有没有什么好的建议!

现在的生命周期,我认为其实有些怪异:

Mounting: componentWillMount -> componentDidMount
Unmounting: componentWillUnmount

Activating: componentWillUpdate -> componentDidMount(This is where the user is confused. I am tampering with the life cycle when I activate it.)
Unactivating: componentWillUnmount

在 Activating 时,其实组件并没有真正的卸载掉,所以能够保存组件实例中的状态;这个阶段本来的执行顺序是 componentWillUpdate -> componentDidUpdate,但是为了方便,我更改了生命周期,这样就与 React 的生命周期有些不一样,不知道大家能否接受,希望能提出一些建议😄。

Uncaught SyntaxError: Unexpected identifier

import 的时候出现这个问题,按照文档来的,结果报错了。中午用的还好好的。请问是什么原因造成的。重新安装npm包也是失败的

跳转页面报错

image
这是我的部分路由配置,通过其属性keepAlive获取需要缓存的组件name,初次页面可以渲染,但是跳转到其他页面

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import routers from 'routes.js';
import {
  Provider as KeepAliveProvide,
  KeepAlive 
} from 'react-keep-alive';
const keepAliveList = routers.map(d => d.keepAlive && d.name);
class RoutesList extends React.Component {
  render() {
    let constRoute = routers.map((item, index) => {
      return (
        <KeepAlive name={item.name} key={item.name + index}>
          <Route exact={true} key={index} path={item.path} name={item.name} component={item.component}>
          </Route>
        </KeepAlive>
      );
    });
    return (
      <div>
        <Switch>
          <KeepAliveProvide include={keepAliveList}>
            {constRoute}
          </KeepAliveProvide>
        </Switch>
      </div>
    );
  }
}

export default RoutesList;

image
请问如何解决

KeepAlive 初始化生成 DIV 导致渲染错误

<main>
       <Switch>
            <Route path="/" exact render={() => <Redirect to="/map" />} /> ,
            <Route exact path="/map">
                <KeepAlive name="map">
                    <MapWrap />  // 百度地图封装 style: { width: 100%, height: 100%}
                </KeepAlive>
            </Route> ,
       </Switch>
</main>

我观察到 <KeepAlive name="map"> 初始化时会有个 div 。初始化时结构大致为

<main>
     <div> // <-- KeppAlive 初始化时生成
              <MapWrap /> // style: { width: 100%, height: 100%}
     </div>
</main>

完成初始化

<main>
      <MapWrap /> // style: { width: 100%, height: 100%}
</main>

百度地图初始化时会计算绑定 DOM( MapWrap ) 的宽高,然后根据这个宽高生成相应的坐标,及中心点坐标。
由于加入的这个 Div 导致 <MapWrap /> 宽高 style: { width: 100%, height: 100%} 计算出来是 0。从而导致百度地图初始化后 坐标点 错误。

这个坑挺隐蔽的~ 找了我2天 =。=

两个解决方案
  • KeepAlive 增加 initClassNameProps,然后用户自行在 CSS 里面处理
  • 增加一个生命周期函数,时间点是 【KeepAlive 初始化的 DIV 从 Dom树移除之后】

前一种办法简单粗暴,后面一种适用范围更广吧(万一有人的需求要在 初始化时 js 操作 Dom 等极端情况)

🐛 重点是要在 文档里面 提到这个 初始化的 DIV 啊 🐛

无法使用lazy()方法引入组件

项目中使用 const OrderRecord = lazy(() => import('%/order/record.jsx')) 引入的组件使用react-keep-alive 不显示。生命周期会走,render不出界面???

Cannot read property 'on' of undefined

App.tsx

import React, { useEffect } from 'react';
import {
  Provider as KeepAliveProvider,
} from 'react-keep-alive'
import Login from './pages/login/Login';
import Index from './pages/index/Index';
import Post from './pages/post/Post'
import Info from './pages/info/Info'
import Person from './pages/person/Person'
import Chat from './pages/chat/Chat'
import {
  BrowserRouter as Router,
  Route,
} from 'react-router-dom';
import Store from './store'

const App: React.FC = () => {
  return (
    <Store>
      <Router>
        <KeepAliveProvider>
          <Route exact path="/" component={Index} />
          <Route exact path="/login" component={Login} />
          <Route exact path="/post" component={Post} />
          <Route exact path="/info" component={Info} />
          <Route exact path="/person" component={Person} />
          <Route exact path="/chat" component={Chat} />
        </KeepAliveProvider>
      </Router>
    </Store>
  );
}

export default App;

demo.tsx:

...
import {useKeepAliveEffect} from 'react-keep-alive';
  // 下拉到底部触发更新
  const loadCallback = () => {
    setPage(page => page + 1)
    getCirclePost()
  }
  useLayoutEffect(() => {
    initCirclePost()
  }, [])  // eslint-disable-line
  useKeepAliveEffect(() => {
    return () => {
    };
  });
...

TypeError:

TypeError: Cannot read property 'on' of undefined
    at useKeepAliveEffect.js:22
    at ma (react-dom.production.min.js:4439)
    at react-dom.production.min.js:5048
    at Wa (react-dom.production.min.js:5067)
    at ui (react-dom.production.min.js:3473)
    at Index.tsx:70
    at c (runtime.js:45)
    at Generator._invoke (runtime.js:264)
    at Generator.e.<computed> [as next] (runtime.js:98)
    at r (asyncToGenerator.js:3)

package.json

"dependencies": {
    "@babel/core": "7.4.3",
    "@babel/plugin-transform-react-jsx-self": "^7.2.0",
    "@babel/plugin-transform-react-jsx-source": "^7.5.0",
    "@svgr/webpack": "4.1.0",
    "@types/jest": "24.0.15",
    "@types/node": "12.6.8",
    "@types/react": "16.8.23",
    "@types/react-dom": "16.8.5",
    "@types/react-router-dom": "^4.3.4",
    "@typescript-eslint/eslint-plugin": "1.6.0",
    "@typescript-eslint/parser": "1.6.0",
    "axios": "^0.19.0",
    "babel-eslint": "10.0.1",
    "babel-jest": "^24.8.0",
    "babel-loader": "8.0.5",
    "babel-plugin-named-asset-import": "^0.3.2",
    "babel-preset-react-app": "^9.0.0",
    "camelcase": "^5.2.0",
    "case-sensitive-paths-webpack-plugin": "2.2.0",
    "css-loader": "2.1.1",
    "dotenv": "6.2.0",
    "dotenv-expand": "4.2.0",
    "eslint": "^5.16.0",
    "eslint-config-react-app": "^4.0.1",
    "eslint-loader": "2.1.2",
    "eslint-plugin-flowtype": "2.50.1",
    "eslint-plugin-import": "2.16.0",
    "eslint-plugin-jsx-a11y": "6.2.1",
    "eslint-plugin-react": "7.12.4",
    "eslint-plugin-react-hooks": "^1.5.0",
    "file-loader": "3.0.1",
    "fs-extra": "7.0.1",
    "html-webpack-plugin": "4.0.0-beta.5",
    "identity-obj-proxy": "3.0.0",
    "is-wsl": "^1.1.0",
    "jest": "24.7.1",
    "jest-environment-jsdom-fourteen": "0.1.0",
    "jest-resolve": "24.7.1",
    "jest-watch-typeahead": "0.3.0",
    "mini-css-extract-plugin": "0.5.0",
    "node-sass": "^4.12.0",
    "optimize-css-assets-webpack-plugin": "5.0.1",
    "pnp-webpack-plugin": "1.2.1",
    "postcss-flexbugs-fixes": "4.1.0",
    "postcss-loader": "3.0.0",
    "postcss-normalize": "7.0.1",
    "postcss-preset-env": "6.6.0",
    "postcss-safe-parser": "4.0.1",
    "react": "^16.8.6",
    "react-app-polyfill": "^1.0.1",
    "react-dev-utils": "^9.0.1",
    "react-dom": "^16.8.6",
    "react-keep-alive": "^2.4.2",
    "react-router-dom": "^5.0.1",
    "redell-ui": "^0.2.7",
    "resolve": "1.10.0",
    "sass-loader": "7.1.0",
    "semver": "6.0.0",
    "style-loader": "0.23.1",
    "terser-webpack-plugin": "1.2.3",
    "ts-pnp": "1.1.2",
    "typescript": "^3.4.3",
    "url-loader": "1.1.2",
    "use-react-router": "^1.0.7",
    "webpack": "4.29.6",
    "webpack-dev-server": "3.2.1",
    "webpack-manifest-plugin": "2.0.4",
    "workbox-webpack-plugin": "4.2.0"
  },

TS编译错

报错截图:

image

测试代码:

<Provider include="CustomerDetails">
      <KeepAlive name="CustomerDetails">
        <div>CustomerDetails</div>
      </KeepAlive>
</Provider>
// 未使用router

react-keep-alive 版本:

  • v2.1.0

重新active后会丢失scroll位置

试着用bindLifeCycle拦截,手动处理scroll restore,发现在componentWillUnactivate的时候,scrollTop就意外地变成了0

而在onScroll里面每次scroll后记录位置,也会在unactivate后变成0,似乎在挂载到别的地方的时候重新scroll了。

Re-implement react-keep-alive

At present, there are some problems in implementation. The biggest problem is that context can not be easily accessed.

Therefore, I hope to solve this problem through refactoring, I do not know what better ideas you have?

Warning is Ok?

Thank you for this gorgeous component, v2.4 works well with next.js v9.0. But I counter a warning in the console tab in chrome, is a feature or a bug?

image

Not Support Next.js, ReferenceError: document is not defined.

// _app.js

import React from "react";
import { Provider } from "react-redux";
import { Provider as KeepProvider } from "react-keep-alive";
import App, { Container } from "next/app";
import withReduxStore from "../lib/with-redux-store";

class Huaban extends App {
    render() {
        const { Component, pageProps, reduxStore } = this.props;
        return (
            <Container>
                <Provider store={reduxStore}>
                    <KeepProvider include="Example">
                        <Component {...pageProps} />
                    </KeepProvider>
                </Provider>
            </Container>
        );
    }
}

export default withReduxStore(Huaban);

// example.js

import Link from "next/link";
import { KeepAlive } from "react-keep-alive";

let arr = Array.from({ length: 200 }, (v, i) => i);

export default () => (
    <KeepAlive name="Example">
        <ul>
            {arr.map((v, i) => {
                const href = `item?id=${i}`;
                <Link href={href}>
                    <a>
                        <li>item{i}</li>
                    </a>
                </Link>;
            })}
        </ul>
    </KeepAlive>
);

Document and Window don't exist in Node server.

引入keep-alive无法使用 路由内部抛错出来

错误提示: react-dom.production.min.js:110 DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

代码
import { HashRouter, Route, Switch } from 'react-router-dom';
import {
Provider as KeepAliveProvider,
KeepAlive,
} from 'react-keep-alive';

import App from '../pages/app';
import Demo from '../pages/demo';

const Router = (
















);
export default Router;

main.js

import Api from './api/index';
import Util from './utils';

import Router from './routes';
import 'antd/dist/antd.css';

Object.assign(global, antd);
global.Api = Api;
global.Util = Util;

ReactDOM.render(
Router,
document.getElementById('app'),
);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.