关于react中列表渲染的局部刷新问题

目录
  • react中列表渲染的局部刷新
  • react实现实时/局部刷新
    • 初始做法示例
    • 增加数据
    • 修改数据
    • 删除数据

react中列表渲染的局部刷新

最近在写demo的时候遇到一个更新列表中某个的对象的某个值,最期待的结果肯定是局部刷新,但是我们往往在改变值之后会遇到全局都刷新的问题,以下为个人实验出来的一个小技巧。

首先我有以下数据需要通过react的列表方法渲染:

let list=[
    {
        id:1,
        show:false
    },
    {
        id:2,
        show:false
    },
    {
        id:3,
        show:false
    }
]

我们通过以下react方法进行渲染:

render(){
    return (
        {list.map((val)=>{
            <DemoComponent val={val}/>
        })}
    )
}

在这里我们需要重新写一个DemoComponent的组件:

import React,{Component} from 'react';
export class DemoComponent extends Component{
    render(){
        <div>
          <div>this.props.val.id</div>
          <button onClick={()=>this.toggleDialog()}>toggle</button>  
        </div>
    }
    toggleDialog(){
        // 更改val.showDialog相关操作。
    }
    shouldComponentUpdate(nextProps){
        return JSON.stringify(nextProps) !== JSON.stringify(this.props);
    }
}

当我们点击第一个button,这个时候就能达到局部刷新,只刷新第一个DemoComponent组件的效果了。

但以上操作是什么原理呢?

首先,大家平时都推荐使用的PureComponent不能在这里使用,因为这个组件没有shouldComponentUpdate这个钩子函数,虽然PureComponent也有对比props和nextProps并自行判断当前组件是否需要重新渲染的功能,但是这个对比对对象是没有用的,因为{} === {}是返回false的(对这个知识点不理解的朋友可以去看看堆栈相关的知识),数组同理。

那么为了让其他列表组件没有必要多去render一次,所以我在shouldComponentUpdate中取了个巧,直接JSON.stringify,将两个对象转换成字符串进行比较,这样就方便的多。

当然这里也是自己为了不去写一个isEqual方法而偷懒的做法,这样做的好处是简单方便,也节省时间(isEqual方法必然会for-in循环,对于更复杂的情况甚至需要递归,在内存消耗和时间复杂度上肯定会比JSON.stringify严重),缺点在于可拓展性不高,如果是个数组,就比较头疼。

react实现实时/局部刷新

在React项目中,经常会遇到诸如:删除某一行的同时同时刷新表格展示最新的表格,而不是删除后,手动刷新。

原先是在删除时再次调用生命周期函数中展示表格列表的函数,但会影响性能。

总结:通过JS数组修改usestate中的状态。

初始做法示例

useEffect(() => {
        httpOffer()
    }, [])
//获取列表
    const httpOffer = () => {
        offerList()
            .then(res => {
                // console.log('offer', res)
                if (res.status === 200) {
                    if (res.data.code === 0) {
                        const data = res.data.data
                        data.length > 0 && data.forEach(el => {
                            el.key = el.id
                        });
                        setOffers(data)
                    } else {
                        message.error(res.data.msg)
                    }
                } else {
                    message.info('network failed')
                }
                setLoading(false)
            })
            .catch(err => {
                setLoading(false)
                throw err
            })
    }
const showModalDel = (id) => {
        delOffer({ id })
            .then(res => {
                if (res.status === 200) {
                    if (res.data.code === 0) {
                        //之前的做法,刷新页面
                        httpOffer()
                        message.info(res.data.msg)
                    } else {
                        message.error(res.data.msg)
                    }
                } else {
                    message.error('Network failed!')
                }
            })
            .catch(err => {
                throw err
            })
    }

目前可以使用JS数组和usestate进行同样的操作。

增加数据

addOffer(params)
                .then(res => {
                    if (res.status === 200) {
                        if (res.data.code === 0) {
                            let data = res.data.data
                            //重点
                            setOffers([...offers, { key: data.id, id: data.id, ...params}])
                            
                            message.info(res.data.msg)
                            setVisible(false)
                        } else {
                            message.error(res.data.msg)
                        }
                    } else {
                        message.error('Network failed!')
                    }
                })
                .catch(err => {
                    console.log(err)
                })

修改数据

editOffer(params)
                .then(res => {
                            //重点
                            setOffers(offers.map(item => {
                                if(item.id === params.id){
                                    item.id = params.id,
                                    item.adv_id = params.adv_id,
                                }
                                return item
                            }))
                            setVisible(false)
                })
                .catch(err => {
                    console.log(err)
                })

删除数据

const showModalDel = (id) => {
        delOffer({ id })
            .then(res => {
                 //重点
                 setOffers(offers.filter(item => item.id != id ))
                 message.info(res.data.msg)
            })
            .catch(err => {
                throw err
            })
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈从React渲染流程分析Diff算法

    React中最神奇的部分莫过于虚拟DOM,以及其高效的Diff算法.这让我们可以无需担心性能问题而"毫无顾忌"的随时"刷新"整个页面,由虚拟DOM来确保只对界面上真正变化的部分进行实际的DOM操作.React在这一部分已经做到足够透明,在实际开发中我们基本无需关心虚拟DOM是如何运作的.然而,理解其运行机制不仅有助于更好的理解React组件的生命周期,而且对于进一步优化React程序也会有很大帮助. 1.什么是虚拟DOM 在React中,render执行的结果得到的

  • React 组件渲染和更新的实现代码示例

    最近一直写React,慢慢就对里面的一些实现很好奇.最好奇的就是自定义标签的实现和this.setState的实现.这里不分析JSX是如何解析的,所有组件都用ES5方式编写. 组件渲染 渲染时候,我们会调用render方法.类似下面这样: var SayHi = React.createClass({ getInitialState: function() { return {verb: 'say:'}; }, componentWillMount: function() { console.l

  • 详解React服务端渲染从入门到精通

    前言 这篇文章是我自己在搭建个人网站的过程中,用到了服务端渲染,看了一些教程,踩了一些坑.想把这个过程分享出来. 我会尽力把每个步骤讲明白,将我理解的全部讲出来. 文中的示例代码来自于这个仓库,也是我正在搭建的个人网站,大家可以一起交流一下.示例代码因为简化,与仓库代码有些许出入 本文中用到的技术 React V16 | React-Router v4 | Redux | Redux-thunk | express React 服务端渲染 服务端渲染的基本套路就是用户请求过来的时候,在服务端生成

  • React学习笔记之列表渲染示例详解

    前言 本文主要给大家介绍了关于React列表渲染的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 示例详解: 列表渲染也很简单,利用map方法返回一个新的渲染列表即可,例如: const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li>{number}</li> ); ReactDOM.render( <ul>{listItems}<

  • 关于react中列表渲染的局部刷新问题

    目录 react中列表渲染的局部刷新 react实现实时/局部刷新 初始做法示例 增加数据 修改数据 删除数据 react中列表渲染的局部刷新 最近在写demo的时候遇到一个更新列表中某个的对象的某个值,最期待的结果肯定是局部刷新,但是我们往往在改变值之后会遇到全局都刷新的问题,以下为个人实验出来的一个小技巧. 首先我有以下数据需要通过react的列表方法渲染: let list=[     {         id:1,         show:false     },     {    

  • vue中v-for指令完成列表渲染

    目录 1.列表遍历 2.Vue中key的作用 3.列表过滤 本文就Vue中列表渲染做个简单总结和使用演示: 列表渲染是用v-for指令根据绑定一组元素的选项来完成的,渲染格式可以自定义. 1.列表遍历 最基本的使用案例1: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compa

  • React 中的列表渲染要加 key的原因分析

    目录 为什么需要 key? 列表渲染不提供 key 会怎样? 列表渲染的 key 用数组索引会怎样? 应该用什么值作为 key? 结尾 在 React 中我们经常需要渲染列表,比如展示好友列表. 常用写法是用 Arrary.prototype.map 方法,将数组形式的数据映射为 JSX.Element 数组,并嵌入到组件要返回的 JSX.Element 中,如下: function FriendList() { const [items, setItems] = useState(['我们',

  • elementui中使用el-tree控件懒加载和局部刷新

    目录 使用el-tree控件懒加载和局部刷新 懒加载 局部刷新 element-ui el-tree lazy懒加载局部刷新的问题 使用el-tree控件懒加载和局部刷新 懒加载 按照 elementui官方文档示例,效果图 template部分,需要结合 lazy 和 load 一起使用 <el-tree show-checkbox node-key="id" lazy :load="loadNode" :props="defaultProps&q

  • 微信小程序列表渲染功能之列表下拉刷新及上拉加载的实现方法分析

    本文实例讲述了微信小程序列表渲染功能之列表下拉刷新及上拉加载的实现方法.分享给大家供大家参考,具体如下: 微信小程序为2017年1月9日打下了一个特殊的标签,迅速刷爆了网络和朋友圈,最近我也写了一个demo程序体验一把.微信小程序和vuejs有些像,都是数据驱动视图&单向数据绑定,而其体验要比H5页面好很多,这得益于微信环境的支持以及首次运行时同时加载所有页面的处理.本文将分享微信小程序列表的下拉刷新和上划加载的实践. 效果图 首先来看看程序效果图,以下四张图从左至右依次是:下来刷新动画.下拉刷

  • vue中实现页面刷新以及局部刷新的方法

    目录 一.全页面刷新 二.局部刷新 三.应用场景 总结 一.全页面刷新 1.修改 App.vue,代码如下: <template> <div id="app"> <router-view v-if="isRouterAlive" /> </div> </template> <script> export default { name: 'App', provide() { // 父组件中返回要传

  • React中路由参数如何改变页面不刷新数据的情况

    目录 React路由参数改变页面不刷新数据的情况 React页面路由 前端路由和后端路由 前端路由介绍 匹配模式 路由的执行过程 hash模式 history模式 react-router-dom API React路由参数改变页面不刷新数据的情况 路由的参数由于是在componentDidMount中获取的,如果在详情页面再次打开详情页面,由于组件并没有重新渲染,导致didMount不会获取路由参数. 因此在参数改变的时候,可以利用componentWillReceiveProps来更新变量.

  • JavaScript中iframe实现局部刷新的几种方法汇总

    Iframe是一种嵌入网页的框架形式,Web页面可以通过更改嵌入的部分,达到部分内容刷新. Iframe的用法与普通的标签元素DIV类似,可以指定在页面中嵌入的位置.颜色.界面布局等 一.iframe实现局部刷新方法一 <script type="text/javascript"> $(function(){ $("#a1").click(function(){ var name= $(this).attr("name"); $(&q

  • 深入浅析Vue.js 中的 v-for 列表渲染指令

    1 基本用法 当遍历一个数组或枚举一个对象进行迭代循环展示时,就会用到列表渲染指令 v-for. 它的表达式需要结合 in 来使用,类似 item in items 的形式. 1.1 遍历数组 html: <div id="app"> <ul> <li v-for="n in news">{{n.title}}</li> </ul> </div> js: <script> var a

随机推荐