React-组件-原生动画 和 React-组件-性能优化

简介: React-组件-原生动画 和 React-组件-性能优化

React 过渡动画


  • 在 React 中我们可以通过原生的 CSS 来实现过渡动画
  • 但是 React 社区为我们提供了 react-transition-group 帮助我们快速过渡动画
import React from 'react';
import styled from 'styled-components';
const StyleDiv = styled.div`
  width: ${props => props.width};
  height: ${props => props.height};
  background: skyblue;
  opacity: ${props => props.opacity};
  transition: all 3s;
`
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            width: 0,
            height: 0,
            opacity: 0
        }
    }
    render() {
        return (
            <div>
                <StyleDiv {...this.state}/>
                <button onClick={() => {
                    this.btnClick()
                }}>按钮
                </button>
            </div>
        );
    }
    btnClick() {
        this.setState({
            width: '100px',
            height: '100px',
            opacity: 1
        })
    }
}
export default App;




性能优化


嵌套组件的 render 调用


  • 默认情况下, 只要父组件 render 被调用, 那么所有的后代组件的 render 也会被调用



当前存在的问题


  • 如果我们只修改了父组件的数据, 并没有修改子组件的数据, 并且子组件中也没有用到父组件中的数据
  • 那么子组件还是会重新渲染, 子组件的 render 方法还是会重新执行, 这样就带来了性能问题

App.js:

import React from "react";
class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            age: 18
        }
    }
    render() {
        console.log('Home-render-被调用');
        return (
            <div>
                <p>{this.state.age}</p>
            </div>
        );
    }
}
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'yangbuyiya'
        }
    }
    render() {
        console.log('App-render-被调用');
        return (
            <div>
                <p>{this.state.name}</p>
                <button onClick={() => {
                    this.btnClick()
                }}>APP按钮
                </button>
                <Home/>
            </div>
        );
    }
    btnClick() {
        this.setState({
            name: 'Jonathan_Lee'
        });
    }
}
export default App;

可以在 shouldcomponentupdate 该生命周期函数当中进行决定是否需要进行重新渲染,官方文档:https://zh-hans.reactjs.org/docs/react-component.html#shouldcomponentupdate

修改 App.js:

import React from "react";
class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            age: 18
        }
    }
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        return this.state.age !== nextState.age;
    }
    render() {
        console.log('Home-render-被调用');
        return (
            <div>
                <p>{this.state.age}</p>
            </div>
        );
    }
}
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'yangbuyiya'
        }
    }
    render() {
        console.log('App-render-被调用');
        return (
            <div>
                <p>{this.state.name}</p>
                <button onClick={() => {
                    this.btnClick()
                }}>APP按钮
                </button>
                <Home/>
            </div>
        );
    }
    btnClick() {
        this.setState({
            name: 'Jonathan_Lee'
        });
    }
}
export default App;

shouldComponentUpdate 存在的问题


  • 所有需要优化的子组件都需要实现这个方法, 但这个方法并没有技术含量





解决方法


  • 让组件继承于 PureComponent, 让 React 自动帮我们实现

App.js:

import React from "react";
class Home extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            age: 18
        }
    }
    render() {
        console.log('Home-render-被调用');
        return (
            <div>
                <p>{this.state.age}</p>
            </div>
        );
    }
}
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'yangbuyiya'
        }
    }
    render() {
        console.log('App-render-被调用');
        return (
            <div>
                <p>{this.state.name}</p>
                <button onClick={() => {
                    this.btnClick()
                }}>APP按钮
                </button>
                <Home/>
            </div>
        );
    }
    btnClick() {
        this.setState({
            name: 'Jonathan_Lee'
        });
    }
}
export default App;



关于函数式组件的优化方案


对于函数式组件来说:

  • 没有继承关系
  • 没有生命周期方法





函数组件的性能优化


对于类组件, 我们可以通过实现 shouldComponentUpdate 方法, 或者继承于 PureComponent, 来解决性能的优化问题, 但是对于函数式组件, 是没有生命周期的, 是没有继承关系的,那么在函数式组件中如何解决性能优化问题呢?当然是有的,在 React 当中可以通过 React.memo() 高阶函数来定义函数式组件,React.memo() 会返回一个优化后的组件给我们。


App.js:

import React from "react";
const PurHome = React.memo(function () {
    console.log('Home-render-被调用');
    return (
        <div>
            <p>Home</p>
        </div>
    )
});
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'yangbuyiya'
        }
    }
    render() {
        console.log('App-render-被调用');
        return (
            <div>
                <p>{this.state.name}</p>
                <button onClick={() => {
                    this.btnClick()
                }}>APP按钮
                </button>
                <PurHome/>
            </div>
        )
    }
    btnClick() {
        this.setState({
            name: 'Jonathan_Lee'
        })
    }
}
export default App;




state 注意点


  • 永远不要直接修改 state 中的数据
  • 如果要修改 state 中的数据, 必须通过 setState 传递一个新的值

首先来看一个两种不同写法的运行结果吧,第一种就是直接进行修改不通过 setState 进行修改:


App.js:

import React from "react";
class App extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            age: 0
        }
    }
    render() {
        console.log('App-render-被调用');
        return (
            <div>
                <p>{this.state.age}</p>
                <button onClick={() => {
                    this.btnClick()
                }}>APP按钮
                </button>
            </div>
        )
    }
    btnClick() {
        this.state.age = this.state.age + 1;
        this.setState(this.state);
    }
}
export default App;

运行如上代码会发现,页面没有进行重新渲染,就算继承了 PureComponent 也不会进行重新渲染,因为它的底层实现我们在如上的几个代码片段已经实现过了,就算比较当前的值是否和下一次的值是否不同如果不同就重新渲染但是,如上的这种设置方式就会造成两个值是相同的就不会再重新渲染页面。


第二种通过 setState 进行修改:


App.js:

import React from "react";
class App extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            age: 0
        }
    }
    render() {
        console.log('App-render-被调用');
        return (
            <div>
                <p>{this.state.age}</p>
                <button onClick={() => {
                    this.btnClick()
                }}>APP按钮
                </button>
            </div>
        )
    }
    btnClick() {
        this.setState({
            age: this.state.age + 1
        });
    }
}
export default App;

如上之所以可以重新渲染是因为通过 setState 设置值就会触发 React 当中的重新渲染机制,在 PureComponent 底层实现比较的原理比较也是不同的两个值,也会触发页面的更新。


以上两种写法的区别:

  • 第一种这种方式是设置了以前的对象
  • 第二种方式是设置了一个新的对象

最后


本期结束咱们下次再见👋~

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

相关文章
|
2月前
|
存储 前端开发 JavaScript
深入理解React Fiber架构及其性能优化
【10月更文挑战第5天】深入理解React Fiber架构及其性能优化
110 1
|
23天前
|
前端开发 JavaScript 算法
探索现代前端框架——React 的性能优化策略
探索现代前端框架——React 的性能优化策略
20 0
|
23天前
|
前端开发 JavaScript API
探索现代前端框架——React 的性能优化策略
探索现代前端框架——React 的性能优化策略
26 0
|
1月前
|
Web App开发 前端开发 JavaScript
React性能优化指南:打造流畅的用户体验
React性能优化指南:打造流畅的用户体验
|
3月前
|
前端开发 JavaScript
React的事件与原生事件的执行顺序?
React的事件与原生事件的执行顺序?
|
4月前
|
存储 JavaScript 前端开发
探索React状态管理:Redux的严格与功能、MobX的简洁与直观、Context API的原生与易用——详细对比及应用案例分析
【8月更文挑战第31天】在React开发中,状态管理对于构建大型应用至关重要。本文将探讨三种主流状态管理方案:Redux、MobX和Context API。Redux采用单一存储模型,提供预测性状态更新;MobX利用装饰器语法,使状态修改更直观;Context API则允许跨组件状态共享,无需第三方库。每种方案各具特色,适用于不同场景,选择合适的工具能让React应用更加高效有序。
93 0
|
3月前
|
前端开发 JavaScript UED
深入React Hooks与性能优化实践
深入React Hooks与性能优化实践
54 0
|
4月前
|
开发者 搜索推荐 Java
超越传统:JSF自定义标签库如何成为现代Web开发的个性化引擎
【8月更文挑战第31天】JavaServer Faces(JSF)框架支持通过自定义标签库扩展其内置组件,以满足特定业务需求。这涉及创建`.taglib`文件定义标签库及组件,并实现对应的Java类与渲染器。本文介绍如何构建和应用JSF自定义标签库,包括定义标签库、实现标签类与渲染器逻辑,以及在JSF页面中使用这些自定义标签,从而提升代码复用性和可维护性,助力开发更复杂且个性化的Web应用。
79 0
|
4月前
|
前端开发 测试技术 UED
React性能优化的神奇之处:如何用懒加载与代码分割让你的项目一鸣惊人?
【8月更文挑战第31天】在现代Web开发中,性能优化至关重要。本文探讨了React中的懒加载与代码分割技术,通过示例展示了如何在实际项目中应用这些技术。懒加载能够延迟加载组件,提高页面加载速度;代码分割则将应用程序代码分割成多个块,按需加载。两者结合使用,可以显著提升用户体验。遵循合理使用懒加载、编写测试及关注性能等最佳实践,能够更高效地进行性能优化,提升应用程序的整体表现。随着React生态的发展,懒加载与代码分割技术将在未来Web开发中发挥更大作用。
54 0
|
4月前
|
缓存 前端开发 JavaScript
React.memo 与 useMemo 超厉害!深入浅出带你理解记忆化技术,让 React 性能优化更上一层楼!
【8月更文挑战第31天】在React开发中,性能优化至关重要。本文探讨了`React.memo`和`useMemo`两大利器,前者通过避免不必要的组件重渲染提升效率,后者则缓存计算结果,防止重复计算。结合示例代码,文章详细解析了如何运用这两个Hook进行性能优化,并强调了合理选择与谨慎使用的最佳实践,助你轻松掌握高效开发技巧。
108 0