Giter VIP home page Giter VIP logo

react-keeper's Introduction

React-Keeper

A routing library of React, but more than router.
React-Router is a great product, we learned a lot from it. But we truely faced many problems that React-Router doesn't resolve in real using, especially in mobile APPs.
We did a lot to let React-Keeper fit mobile APPs, such as Pages Cache, Extensible Route, Route Filters and so on.
We create a lot of flexible ways, so you can config the router more simplely.
And more...

News

Keeper V2.1 had published !!!
Keeper V2.0 had published !!!

Docs

Route Component                 - ( How to config the Route component )
Link Component                    - ( How to use Link component)
CacheLink Component          - ( How to use CahceLink component )
RouteMapping                       - ( How to config path of route )
Filter                                       - ( How to use filters )
Page Cache                           - ( How to cache pages )
Control                                   - ( Use Router Control in JavaScript code. )
Browser                                  - ( Use React-Keeper in browser. )

Install

npm install react-keeper

Don't use cnpm.

Features

1. Extensible route

You can add route components anywhere,anytime.

const App = ()=> {
  return (
    <HashRouter>
      <div>
        <Route cache component={ Home } path="/"/>
        <Route component={ Products } path="/products"/>
      </div>
    </HashRouter>
  )
}

const Products = ()=> {
  return (
    <div>
      <Route component={ ScienceProducts } path="/sci" />
      <Route component={ DailiUseProducts } path="/dai" />
    </div>
  )
}

ReactDOM.render(<App/>, document.getElementById('root'))

2. Pages Cache

Cache pages' state while not matched, and recover them when matched. Certainly you can config which one to cache.

  1. Use cache tag to cache a page.
  2. Use CacheLink Component to hold a will-unmount's page when open a new page.
 <Route cache component={Home} path='/'/>

 <CacheLink to='/product/ASDFADF'>Detail</CacheLink>

3. Supports loading components dynamicly

Load a component dynamicly when it's route matches, such as:

<Route loadComponent={ (callback)=>{
    import('../Products.js').then((Products)=>{
        callback(Products)
      })
  } } path='/products'/>

4. Supports enter(and leave) filters

  • Enter filters, filters run before a route mount succeed, such as : login's check.
  • Leave filters, filters run before a route unmount succeed, such as : unsubmited form data.
<HashRouter>
  <Route path='/user' component={User}, enterFilter={[ loginFilter, (cb, props)=>{ if(props.access) cb()} ] } />
</HashRouter>

5. Pretty flexible

  • index tag : Index page of a module.
  • miss tag : When miss match.
  • cache tag : Cache a page for preventing to unmount after it mounted.
<HashRouter>
  <div>

    <Route cache component={ Home } path="/"/>

    <Route component={ Products } path="/products" enterFilter={ loginFilter }>
      <Route index component={Enterprise} path="/ep"/>
      <Route miss component={ NotFound }/>
      <Route component={ Detail } path="/item/:id" time={new Date().toLocaleString()}/>
    </Route>

    <Route component={ Home }  path="/products">
      <Route index component={ ProductNav }/>
    </Route>

  </div>
</HashRouter>

6. In the future

  • Supports rendering in server side

  • Memory of scroll position
    Remember the scroll positions of every page, for scrolling to same position when back to a page.

Usage

App.js

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { HashRouter, Route } from 'react-keeper'
import User from './User'
// other import

class App extends Component {
  render(){
    return (
      <HashRouter>
        <div>

          <Route cache component={ Home } path="/"/>

          <Route component={ Products } path="/products" enterFilter={ loginFilter }>
            <Route index component={Enterprise} path="/ep"/>
            <Route miss component={ NotFound }/>
            <Route component={ Detail } path="/item/:id" time={new Date().toLocaleString()}/>
          </Route>

          <Route component={ User }  path="/user"/>

        </div>
      </HashRouter>
    )
  }
}

ReactDOM.render(<App/>, document.getElementById('root'))  

User.js

import React, { Component } from 'react'
import { Link, Route } from 'react-keeper'
// other import

export default class User extends Component {
  render(){
    return (
      <div>
        <ul>
          <Link to='/info'>Info</Link>
          <Link to='/edit'>Edit</Link>
        </ul>

        <div>
          <Route index component={ UserInfo } path='/info'/>
          <Route component={ UserInfoEdit } path='/edit'/>
        </div>
      </div>
    )
  }
}

Support React-Keeper and Author

With your donation, we can do it better.

Contributors

  • Clone Project
git clone [email protected]:lanistor/react-keeper.git

cd react-keeper

npm install
  • Run Example
npm run start

Then open http://127.0.0.1:8600

react-keeper's People

Contributors

dependabot[bot] avatar lanistor avatar linxq avatar vifird avatar weifuchuan avatar yueduz 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-keeper's Issues

constructor and componentDidMount is not called multiple times

Issue

When I change the example for the Detail page to:

import React , { Component } from 'react'

class Detail extends Component {
  constructor(props) {
    super(props)
    console.error('detail: constructor')
  }

  componentDidMount() {
    console.error('detail: component did mount')
  }

  componentWillUnmount() {
    console.error('detail: component will unmount')
  }

  render() {
    console.error('detail: render')

    const props = this.props

    return (
      <div>
        <hr/>
        Detail<br/>
        id: {props.params ? props.params.id : null}<br/>
        time: {props.time}
      </div>
    )
  }
}
export default Detail

The first time I go to a route with the detail component it will show

detail: constructor
detail: component did mount
detail: render

the next route will only print:

detail: render

Expected behavior:

The next route should cause a new component to be initialized (it shouldn't reuse the original one) and then execute componentDidMount.

PAGE INIT:
detail: constructor
detail: component did mount
detail: render
NEXT PAGE:
detail: constructor
detail: component did mount
detail: render
GO BACK:
- nothing if cached -

Why?

Even in the official react documentation it is stated that componentDidMount is a good place to do api requests to load content. This doesn't work right now.

如何传递查询参数?

比如我有一个路由/pageA/;我希望当我手动设置跳转地址为/pageA/?name=xxx并跳转到pageA时能获得查询参数

cache 与 react-iscroll 有冲突

当我给用react-iscroll包的组件上加cache后,切换路由后就无法滚动,必须改变下组件内的state的才能滚动,cache的原理是什么?不过当我用原生的iscroll就没有产生这个问题。
image
seller组件和ratings组件用了react-iscroll包的,goods用的是原生的。
代码地址:https://github.com/Chryseis/elemDemo4React

点击锚点也会触发事件

        <Route enterFilter={AppState.getContent} path="/content">
          <Content content={AppState.content} addComment={AppState.addComment}/>
        </Route>

怎么取路径里的参数

<Route index path="/list/:tag">
      <BlogList data={AppState.data}/>
</Route>

我在BlogList组件里用 console.log(this.props.tag);取不到值
console.log(this.props.params.tag);也取不到

TypeError·Uncaught TypeError: Property '[object Object]' of object [object Array] is not a function

TypeError·Uncaught TypeError: Property '[object Object]' of object [object Array] is not a function
at iterator (webpack:////react-keeper/CacheOfTagControl.js:24:0)
at put (webpack:///
/react-keeper/RouteUtil.js:87:0)
at checkCacheTag (webpack:////react-keeper/Route.js:172:0)
at updateMountStatus (webpack:///
/react-keeper/Route.js:117:0)
at callback (webpack:////react-keeper/RouteUtil.js:166:0)
at checkFilter (webpack:///
/react-keeper/Route.js:104:0)
at callback (webpack:////react-keeper/RouteUtil.js:154:0)
at loadComponent (webpack:///
/react-keeper/Route.js:97:0)
at setToMount (webpack:////react-keeper/Route.js:85:0)
at routeCheckEntry (webpack:///
/react-keeper/Route.js:66:0)
在真机上 华为Mate7/8,传回的错误日志。

npm start出错了

ERROR in ./example/main/App.js Module not found: Error: Cannot resolve module 'react-keeper' in C:\Users\tang\D esktop\react-keeper\example\main @ ./example/main/App.js 15:19-42
npm install也安装了,就是运行不起来

Warning: Failed prop type: Invalid prop `enterFilter` of type `function` supplied to `Route`, expected `array`. in Route (created by CRoutes) in CRoutes in Provider

function requireAuth(nextState, replace) {
    let islogin = auth.isLogin();
    if (islogin == 'true') {

    } else {
        replace('/login')
    }
}


const RouteIndex = (props) => {
    return (
        <div>
            {props.children}
        </div>
    );
};


const CRoutes = () => {
    return (
        <HashRouter>
            <div>
                <Route path='/' component={RouteIndex}>
                    <Route path='login' component={LoginPage}/>
                    <Route index component={HomePage} enterFilter={requireAuth}/>
                </Route>
            </div>
        </HashRouter>
    );
}


 <Provider store={store}>
        <CRoutes/>
    </Provider>

动态加载组件

<Route loadComponent={ (callback)=>{
System.import('../Products.js').then((Products)=>{
callback(Products)
})
} } path='/products'/>
这个方法并不能动态加载组件啊

链接跳转后的页面缓存问题

HI,现在在2.0.6和2.0.7版本遇到的一个问题是,通过一个链接传不同的参数跳转到一个页面,比如这样的方式:Control.go('/a', {id: 1})或<Link to"/a/1">,这样的方式,路由配置为

但是现在发现,但是现在通过以下步骤跳转页面:首页--><Link to"/a/1">-->首页--><Link to"/a/2">
发现并未走到2页面,依然还是跳转到1页面,请问有没有遇到这样问题的同学?怎么解决的呢?

结合ReactCSSTransitionGroup使用,会执行两次DidMount

image
如果去掉ReactCSSTransitionGroup的话 一切就正常了

按理说,在返回的时候ReactCSSTransitionGroup会重新挂载组件,但是怎么会出现卸载后再挂载呢

想问下 这个问题能解决吗?有什么针对性的方案吗

Route配置的时候的 loadComponent

你好,按照文档写的情况loadComponent 用了 System.import 是有引入外部的 Systemjs还是什么情况呢?package.json,没看到相关的信息。

注:我的 node 版本是7.9

page cache

请问一下,没有什么办法改变缓存页面的某个state,我对首页设置cache
<Route index component={Home} path= '/home' cache />
从其他页面返回后,我想根据路由传回的参数改变首页某项state的值,其他状态不变,不知道有没有什么好的办法解决

在routers文件替换为keeper后, {this.props.children}不起作用了.

routers.js:

<Route component={ PageHome } path="/" >
            <Route component={PageZuzhi} path="zuzhi" />
            <Route component={PageJiceng} path="jiceng" />
        </Route>

PageHome 组件:

<div className="container" id="container">
     {this.props.children}
     <Menu menu={menu} selectedTab={selectedTab} onChange={handleChange} />     
 </div>

问题: 不支持this.props.children 调用吗?

一个版本问题

@vifird 版本2.0.6Cachelink是可以缓存的,Control.replace不能修改state,最新版可以Control.replace并修改state,Cachelink不能缓存,不知道是不是我的代码写错了,我用的是这样

Error: Cannot call a class as a function

// main.jsx
import React from 'react'
import ReactDOM from 'react-dom'

import App from './App'

ReactDOM.render(
  <App />, // 修改为 <div>Page</div> 可正常运行
  document.querySelector('#root')
)
// App.jsx
import React, { Component } from 'react'
import { HashRouter as Router, Route } from 'react-keeper'

import Home from './Home'
import User from './User'

class App extends Component {
  render = () => {
    return (
      <Router>
        <div>
          <Route cache index component={ Home } path="/" />
          <Route component={ User } path="/user" />
        </div>
      </Router>
    )
  }
}

export default App
// Home.jsx
import React, { Component } from 'react'

class Home extends Component {
  render = () => {
    return (
      <div>Home Page</div>
    )
  }
}

export default Home
// User.jsx
// User 与 Home 一样

package.json 依赖

  "devDependencies": {
    "babel-core": "6.25.0",
    "babel-loader": "7.1.1",
    "babel-plugin-syntax-dynamic-import": "6.18.0",
    "babel-plugin-transform-class-properties": "6.24.1",
    "babel-preset-env": "1.6.0",
    "babel-preset-react": "6.24.1",
    "webpack": "3.4.1"
  },
  "dependencies": {
    "react": "15.6.1",
    "react-dom": "15.6.1",
    "react-keeper": "2.0.7"
  }

webpack.config.js:

const { resolve } = require('path')

module.exports = {
  entry: resolve(__dirname, './main.jsx'),
  output: {
    path: resolve(__dirname, './dist'),
    filename: 'bundle.js',
  },
  resolve: {
    mainFields: ['jsnext:main', 'module', 'main'],
    extensions: ['.js', '.jsx', '.json'],
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [['env', { modules: false }], 'react'],
              plugins: ['transform-class-properties'],
            },
          },
        ],
      },
    ],
  },
}

执行 ./node_modules/.bin/webpack -w 之后,编译通过,打开页面无法正常渲染,console 输出:

classCallCheck.js?66b9:7 Uncaught TypeError: Cannot call a class as a function
    at exports.default (classCallCheck.js?66b9:7)
    at TestComp (TestComp.jsx?36e2:3)
    at Object.render (index.js?fa45:44)
    at eval (ReactCompositeComponent.js?063f:795)
    at measureLifeCyclePerf (ReactCompositeComponent.js?063f:75)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js?063f:794)
    at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js?063f:821)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js?063f:361)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js?063f:257)
    at Object.mountComponent (ReactReconciler.js?c56c:45)

希望得到你们的帮助,解决这个问题,好更进一步的了解 react-keeper,谢谢。

route nested and miss page issues

I get some weird issues here when i create a nested routes .

not working in :

  • if i visited category first and change to home's children.
  • visit non-exsiting state never show miss ( working after refresh page )

toggle tag

// App
class App extends Component {
    render() {
        return (
            <HashRouter>
                <div>

                    <Route cache index component={ Home } path="/home" />

                    <Route cache
                           loadComponent={cb => require.ensure([], require => cb(require('./ShoppingCart').default))}
                           path="/shoppingCart" />

                    <Route cache
                           loadComponent={cb => require.ensure([], require => cb(require('./Category').default))}
                           path="/category" />

                    <Route miss
                           component={Miss}
                           path="miss" />

                    <Footer />
                </div>
            </HashRouter>
        );
    }
}

// Home
class Home extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
    }

    render() {
        return (
            <div className="home">
                <div>{aHomeHeaderNavs()}</div>
                <Route cache="parent" component={ HomeTab1 } path="/tab1" />
                <Route cache="parent" component={ HomeTab2 } path="/tab2" />
                <Route cache="parent" component={ HomeTab3 } path="/tab3" />
                <Route cache="parent" component={ HomeTab4 } path="/tab4" />
                <Route cache="parent" component={ HomeTab5 } path="/tab5" />
            </div>
        );
    }
}

按照示例的用*来匹配404页面时会出现重复,/* 对应的页面也会出现

代码如下:

class Test extends Component{
	render(){
		return (
			<div>
				<Main />
				<Route cache component={ Chat } path="/chat" />
				<Route component={ Setting } path="/setting" />
				<Route component={ Setting } path="/*" />
			</div>
		)
	}
}
class App extends Component{
	render(){
		return (
			<HashRouter>
			  <div>
			  	<Link className='dsfds' to='/welcome'>welcome</Link>
			  	<Link className='dsfds' to='/login'>login</Link>
			  	<Link className='dsfds' to='/main'>main</Link>
			  	<Link className='dsfds' to='/main/setting'>Setting</Link>
			  	<Link className='dsfds' to='/main/chat'>chat</Link>
				<Route component={ Welcome } path="/welcome" />
				<Route component={ Login } path="/login" />
				<Route component={ Test } path="/main" />
			  </div>
			</HashRouter>
		)
	}
}```

clear cache page

How to programmably clear a cached page .
May like this :

// after login
reactKeeper.clearCache('index.home.tab1')

关于cache页面渲染的问题

你好,我在使用keeper的过程中遇到了一个问题,我的首页(Index)路由设置了cache和index属性,但是我发现当我在其他页面时,这个页面经常还会刷新,而且这种刷新只触发render,导致在DOM渲染完成后绑定得效果(比如Swiper插件渲染的效果)都不会重新渲染,从而导致页面显示效果出错,请问这种问题有解决办法么?

如何将缓存的页面给清除

在当前页面访问下一页面时候,缓存当前页面;在当前页面执行Control.go(-1)的时候,释放掉当前页面

地址改变不重刷新组件

/list 到 /list?tga=linux 不刷新,
如果/list被设置了index,则/到/list也不刷新

我认为即使是相同的组件,地址不同也应该要刷新.
用了BrowserRouter组件#号后面的改变则不刷新,keeper实现刚好相反

怎么设置默认路由

                <Route component={Content} path="/content" />
                <Route component={List} path="/"  />

这样写的话,我这里无论什么路径{List}都被显示.

使用动态路由 的一些问题

目前安装文档配置动态路由,出现下面的问题
wechatimg4
代码:
wechatimg5
wechatimg6
可能是我的使用问题,麻烦提供详尽的文档谢谢。

如何不把页面记录history?

请问如果我有一个搜索的过渡页不想把它记录到history中,比如页面1->页面2->页面3,我想在页面3返回时直接到页面1(不确定页面),不经过页面2,现在有这样的功能么?如果有应该如何做呢?谢谢

enterFilter

router好像没有等到enterFilter执行完成就开始渲染了,我放在enterFilter中的ajax总会被请求两次

没找到leaveHook或者类似的相关react-router的用法

切换使用了一个月了,没有啥问题,今天想找到一个类似router leave的钩子,还有Link这种携带参数,react-router有param可以配置多个,不知道这个怎么配置多个,我现在是组合String 传或者Control跳转携带Object的。
谢谢。麻烦了。

Control.path 得不到当前路径

2017-05-01 23-12-29

<Route enterFilter={ AppState.setContent } controlPath={Control.path} path="/content/">
  <Content source={AppState.content} />
</Route>
  setContent(callback, props) {
    console.log(callback);
    console.log(props);
    axios.get("/api/content/123")
      .then((res) => {
        this.content = res.data;
        // console.log(res.data);
      })
      .catch((error) => console.log(error))
  }

子组件写法

能不能支持这种写法

 <Route index cache>
                      <List store=AppStore/>
</Route>

这样写传参数很麻烦啊
<Route component={Content} path="/content" />

replace跳转页面如何获取state

使用replace跳转页面,但是在跳转后的页面无法获取到state的值,this.controlState为空,请指教如何获取state值呢?

怎么让两个路由都指向同一个页面

<Route path="/topics/:tab" component={HomePage}/>
<Route path="/user" component={HomePage}/>

这个在react-router下,都指向同一个页面,并且路由切换的时候组件不会重新挂载。但keeper会重新挂载。

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.