Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >关于React中状态保存的研究

关于React中状态保存的研究

作者头像
糊糊糊糊糊了
发布于 2018-05-09 07:58:05
发布于 2018-05-09 07:58:05
4.6K00
代码可运行
举报
文章被收录于专栏:糊一笑糊一笑
运行总次数:0
代码可运行

在使用react搭配react-router做应用的时候,你可能遇到这样的问题,当我从第一个页面过渡到第二个页面,然后返回之后,发现之前的页面的状态全部不见了,即回到了初始的状态。

这点在页面存在多个TAB页或者多条件筛选的时候体验会更加明显,这时候我又不得不点击我之前选择的页签,重新选择筛选条件,然后再进行搜索。因此,在这种情况下,保存之前的状态显得尤为亟待解决,下面是自己实践出来的几种方法,做一下分享,同时希望和各位一起探讨,看能不能有什么更好的办法。

代码:github

解决方案一:子路由方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// normal/routers/Books/Books.js
module.exports = {
    path: 'books',
    getComponent(nextState, cb) {
        require.ensure([], (require) => {
            cb(null, require('./components/Books'))
        })
    },
    getChildRoutes(partialNextState, cb) {
        require.ensure([], (require) => {
            cb(null, [
                require('./book')
            ])    
        })
    }
};

// normal/routers/Books/book.js
module.exports = {
    path: 'book/:id',
    getComponent(nextState, cb) {
        require.ensure([], (require) => {
            cb(null, require('./components/Book'))
        })
    }
};

配置图书列表下的嵌套路由可以查看图书详情。具体的路由跳转如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// normal/routers/Books/components/Books.js

onLookDetail(id, book, index) {
    this.setState({ activeIndex: index });
    this.props.router.push({ pathname: `books/book/${id}`, query: book });
}

render() {
    const { children } = this.props;
    // ...
    
    // 如果有字路由组件,就渲染子组件
    if (children) {
        return children;
    }
    // ...
}

效果如下:

可以看到,当从详情页面返回时,点击的激活状态依旧可以保存,但是列表滚动的高度并不能够保存,关于高度的恢复在下面会讲到。

解决方案二:当前页面弹窗

不占用路由,在当前页面直接已弹窗的形式加载详情页面。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// normal/routers/Books/components/Books.js
constructor(props) {
    super(props);
    this.state = {
        activeIndex: -1,
        books: [],
        modal: false
    };
}

onLookDetail(id, book, index) {
    this.setState({ activeIndex: index, modal: true });
}

onDetailBack() {
    this.setState({ modal: false });
}

render() {
    {
      // 根据state中的modal值来判断当前弹窗是否显示
      // 其实就是Book.js中的代码
      modal && (
        <div style={ styles.modal }>
            <Flex direction="column" style={ styles.wrapper }>
                <div style={ styles.header }>
                    <NavBar 
                        mode="dark"
                        leftContent="返回"
                        icon={<Icon type="left" />}
                        onLeftClick={ this.onDetailBack.bind(this) }>
                        图书详情
                    </NavBar>
                </div>
                <div style={ styles.content }>
                    <Card>
                        <Card.Header
                            title="标题"
                            thumb="xxx"
                            extra={ <span>{ book.title }</span> }/>
                        <Card.Body>
                            <div>{ book.description }</div>
                        </Card.Body>
                        <Card.Footer 
                            content="footer content" 
                            extra={<div>{ book.price }</div>} />
                    </Card>
                </div>
            </Flex>
        </div>
        )
    }
}

效果如下:

看上去效果十分好,既能保存状态,也能保存滚动条的高度。

解决方案三:本地存储/redux数据仓库/参数传递

我把这三种方案归结为一种,因为实际上是在离开列表组件的时候保存当前的状态,然后在回到页面的时候根据之前保存的状态来进行现场恢复而已。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// src/routers/Books/components/Books.js

// 配合shouldComponentUpdate声明周期函数,避免不必要的渲染
shouldComponentUpdate(nextProps, nextState) {
    return !is(fromJS(this.props.books), fromJS(nextProps.books))
        || !is(fromJS(this.state), fromJS(nextState));
}

// 更新当前选中的activeIndex值,将其同步至redux中,然后再进行路由跳转
onLookDetail(id, book, index) {
    const { actions } = this.props;
    actions.updateBooks({ activeIndex: index });
    this.props.router.push({ pathname: `book/${id}`, query: book });
}

// 从redux中取值进行现场恢复
render() {
    const { books } = this.props;
    const list = books.books;
    const activeIndex = books.activeIndex;
    
    // ...
}

// src/reudx/reudcers/books.js
const initialState = {
    books: [],
    activeIndex: -1
};

效果如下:

效果和字路由方式相同,依然存在滚动高度不能保存的问题。

滚动高度问题

下面来谈谈如何解决滚动高度的问题,综合起来还是一种恢复现场的方式。在页面即将离开之前,保存之前的scrollTop值,然后再次回到这个页面的时候,恢复滚动高度即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// src/reudx/reudcers/books.js
const initialState = {
    books: [],
    activeIndex: -1,
    // 添加scrollTop
    scrollTop: 0
};

// src/routers/Books/components/Books.js
componentDidMount() {
    const { actions, books } = this.props;
    const content = this.refs.content;
    const scrollTop = books.scrollTop;
  
    if (scrollTop > 0) {
        content.scrollTo(0, scrollTop);
    }
  
    setTimeout(() => {
        actions.getBooks();
    }, 150);
}

componentWillUnmount() {
    const content = this.refs.content;
    const { actions } = this.props;
    actions.updateBooks({ scrollTop: content.scrollTop });
}

效果如下:

尝试方案:react-keeper

github上搜索看到了这个库,类似于react-router的一个翻版,同时在react-router的基础上增加了类似于vue-router中的keep-alive功能,这点暂时占坑,等做了案例之后再来填坑。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
react+redux+webpack教程3
现代web页面里到处都是ajax,所以处理好异步的代码非常重要。 这次我重新选了个最适合展示异步处理的应用场景——搜索新闻列表。由于有现成的接口,我们就不用自己搭服务了。 我在网上随便搜到了一个新闻服务接口,支持jsonp,就用它吧。 一开始,咱们仍然按照action->reducer->components的顺序把基本的代码写出来。先想好要什么功能, 我设想的就是有一个输入框,旁边一个搜索按钮,输入关键字后一点按钮相关的新闻列表就展示出来了。 首先是action,现在能想到的动作就是把新闻列表放到仓库里,
前朝楚水
2018/04/03
1.1K0
手把手教你全家桶之React(二)
前言 上一篇已经讲了一些react的基本配置,本遍接着讲热更新以及react+redux的配置与使用。 热更新 我们在实际开发时,都有用到热更新,在修改代码后,不用每次都重启服务,而是自动更新。并而不
用户2145235
2018/05/18
1.8K0
React项目的服务端渲染改造(koa2+webpack3.11)
选型思路:实现服务端渲染,想用React最新的版本,并且不对现有的写法做大的改动,如果一开始就打算服务端渲染,建议直接用NEXT框架来写 项目地址:https://github.com/wlx200510/react_koa_ssr 脚手架选型:webpack3.11.0 + react Router4 + Redux + koa2 + React16 + Node8.x 主要心得:对React的相关知识更加熟悉,成功拓展自己的技术领域,对服务端技术在实际项目上有所积累 注意点:使用框架前一定确认当前web
卡少
2018/05/16
1.4K0
Redux系列x:源码分析
写在前面 redux的源码很简洁,除了applyMiddleware比较绕难以理解外,大部分还是 这里假设读者对redux有一定了解,就不科普redux的概念和API啥的啦,这部分建议直接看官方文档。
IMWeb前端团队
2017/12/29
1.3K0
应用connected-react-router和redux-thunk打通react路由孤立
在我们开发过程中,很多时候,我们需要让组件共享某些数据,虽然可以通过组件传递数据实现数据共享,但是如果组件之间不是父子关系的话,数据传递是非常麻烦的,而且容易让代码的可读性降低,这时候我们就需要一个 state(状态)管理工具。常见的状态管理工具有 redux,mobx,这里选择 redux 进行状态管理。值得注意的是 React 16.3 带来了全新的Context API,我们也可以使用新的 Context API 做状态管理。Redux 是负责组织 state 的工具,但你也要考虑它是否适合你的情况。
Run丘比特
2020/11/19
2.6K0
应用connected-react-router和redux-thunk打通react路由孤立
深入理解 Redux 原理及其在 React 中的使用流程
大家好,我是腾讯云开发者社区的 Front_Yue,随着前端开发技术的不断发展,开发者们越来越注重应用的可维护性、可扩展性和稳定性。而状态管理库 Redux 的出现,为我们的应用提供了一种优雅的状态管理方案。本篇文章将详细介绍 Redux 的原理以及如何在 React 项目中使用 Redux。
Front_Yue
2024/06/10
9590
深入理解 Redux 原理及其在 React 中的使用流程
react+redux+webpack教程2
先弄个什么例子呢?如果是现代的MVVM框架,可能会用双向绑定来吸引你。那react有双向绑定吗? 没有。 也算是有吧,有插件。不过双向绑定跟react不是一个路子的。react强调的是单向数据流。 当然,即便是单向数据流也总要有个数据的来源,如果数据来源于页面自身上的用户输入,那效果也就等同于双向绑定了。 下面就展示一下如何达到这个效果。我们来设计一个登录的场景,用户输入用户名后,会在问候语的位置展示用户名,像下这样: ---- 早上好,Mark 用户名: 密 码: 登 录 ---- 预警一下先,我要用
前朝楚水
2018/04/03
1.4K0
React之redux学习日志(redux/react-redux/redux-saga)
redux官方中文文档:https://www.redux.org.cn/docs/introduction/CoreConcepts.html
全栈程序员站长
2021/04/07
6570
React之redux学习日志(redux/react-redux/redux-saga)
【React】211- 2019 React Redux 完全指南
https://juejin.im/post/5cac8ccd6fb9a068530111c7
pingan8787
2019/07/23
4.5K0
【React】211- 2019 React Redux 完全指南
React渲染问题研究以及Immutable的应用
写在前面 这里主要介绍自己在React开发中的一些总结,关于react的渲染问题的一点研究。 另外本人一直希望在React项目中尝试使用,因此在之前已经介绍过immutable的API,可以参看这里Immutable日常操作之深入API,算是对其的一个补充。 本文所有代码请参看github仓库:https://github.com/Rynxiao/immutable-react 渲染房间列表 这个例子主要是写了同时渲染1000个房间,如果我添加一个房间或者修改一个房间,在react中不同的实现方式下rend
糊糊糊糊糊了
2018/05/09
2.1K0
React渲染问题研究以及Immutable的应用
webpack4 中的 React 全家桶配置指南,实战!
点赞再看,养成习惯本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。
前端小智@大迁世界
2022/06/15
2.1K0
webpack4 中的 React 全家桶配置指南,实战!
generator-ivweb 基于react-redux的多页脚手架
generator-ivweb是由腾讯IVWEB团队设计的脚手架,基于团队开源项目feflow,feflow是一个前端集成开发环境,详细介绍可以看这里:feflow。
腾讯IVWEB团队
2020/06/24
5430
hook+react-redux让redux使用更简单
实际上,在react-redux中我们只需要了解这三个概念即可使用redux,而实际上这些也不难理解。我们只要掌握一些关键的api,尤其是hook,就可以很轻松地在我们的项目中加入redux
源心锁
2022/08/12
8870
hook+react-redux让redux使用更简单
[OHIF-Viewers]医疗数字阅片-医学影像-辅助工具-Redux DevTools-DevTools for Redux with hot reloading, action replay,
Redux DevTools for debugging application's state changes. The extension provides power-ups for your Redux development workflow. Apart from Redux, it can be used with any other architectures which handle the state.
landv
2020/07/23
8320
[OHIF-Viewers]医疗数字阅片-医学影像-辅助工具-Redux DevTools-DevTools for Redux with hot reloading, action replay,
【taro react】---- 【使用 redux 的配置笔记】
1. 目标 学会 yarn 或 npm 安装中间件 学会配置 redux 的 store 学会 store 的接入和使用 2. 安装中间件 安装redux用到的中间件: redux react-redux redux-thunk redux-logger $ yarn add redux react-redux redux-thunk redux-logger # 或者使用 npm $ npm install --save redux react-redux redux-thunk redux-logge
Rattenking
2022/01/06
1.3K0
redux源码解析
applyMiddleware.js import compose from './compose' /** * Creates a store enhancer that applies middleware to the dispatch method * of the Redux store. This is handy for a variety of tasks, such as expressing * asynchronous actions in a concise manner,
theanarkh
2019/03/06
1.2K0
阅读redux源码
提供了和双向绑定思想不同的单向数据流,应用状态可以预测,可以回溯,易于调试。使用redux之初的人可能会很不适应,改变一个状态,至少写三个方法,从这点上不如写其他框架代码易于理解,但是自从配合使用redux-logger一类的logger插件,就感觉到了redux的优势。状态改变很清晰,很容易了解发生了什么。
frontoldman
2019/09/02
8990
你想要的——redux源码分析
备注:例子中结合的是react进行使用,当然redux不仅仅能结合react,还能结合市面上其他大多数的框架,这也是它比较流弊的地方
can4hou6joeng4
2023/11/30
2580
从零搭建一个 webpack 脚手架工具(二)
配置完有关 CSS loader 后,还有一个问题,我们不想将 CSS 都插入到 style 标签中,如果 CSS 样式代码很多,会导致生成的 HTML 文件很大,我们希望使用 <link> 标签引入打包后的 CSS 文件(将 CSS 单独提取出来),这时候就要使用一个插件:mini-css-extract-plugin。
多云转晴
2019/12/16
1.5K0
Redux开发实用教程
为了帮助大家快速上手什么是Redux开发,在这本节中将向大家介绍什么是Redux开发所需要的一些什么是Redux必备基础以及高级知识。
CrazyCodeBoy
2019/12/10
1.5K0
Redux开发实用教程
相关推荐
react+redux+webpack教程3
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验