首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么状态更新函数比将状态设置为纯值要快?

为什么状态更新函数比将状态设置为纯值要快?
EN

Stack Overflow用户
提问于 2022-04-24 17:24:58
回答 1查看 43关注 0票数 1

对于上下文,我有一个web应用程序,它在React中显示一个图像--引导容器组件(Arena),它保存一个图像,用户可以在其中查找和查找特定的字符。

另外,我创建了一个div组件(CustomCursor),其中将背景设置为放大镜SVG图像。

Arena组件通过OnMouseMove处理程序函数(handleMouseMove)跟踪鼠标位置,并将这些坐标作为支持传递给CustomCursor组件。

以下是我的竞技场组件代码:

代码语言:javascript
复制
import { useState, useEffect } from 'react';
import { Container, Spinner } from 'react-bootstrap';
import CustomCursor from '../CustomCursor/CustomCursor';
import Choices from '../Choices/Choices';
import { getImageURL } from '../../helpers/storHelpers';

import './Arena.scss';

export default function Arena(props) {

    const [arenaURL, setArenaURL] = useState('');
    const [loaded, setLoaded] = useState(false);
    const [clicked, setClicked] = useState(false);
    const [x, setX] = useState(0);
    const [y, setY] = useState(0);

    function handleClick(e) {
        setClicked(true);
    }

    function handleMouseMove(e) {
        setX(prevState => { return e.clientX });
        setY(prevState => { return e.clientY });
    }

    useEffect(() => {
        retreiveArena();

        // FUNCTION DEFINITIONS 
        async function retreiveArena() {
            const url = await getImageURL('maps', 'the-garden-of-earthly-delights.jpg');
            setArenaURL(url);
            setLoaded(true);
        }
    }, [])

    return (
        <Container as='main' fluid id='arena' className='d-flex flex-grow-1 justify-content-center align-items-center' onClick={handleClick}>
            {!loaded &&
                <Spinner animation="border" variant="danger" />
            }
            {loaded &&
                <img src={arenaURL} alt='The Garden of Earthly Delights triptych' className='arena-image' onMouseMove={handleMouseMove} />
            }
            {clicked &&
                <Choices x={x} y={y} />
            }
            <CustomCursor x={x} y={y} />
        </Container>
    )
}

以下是我的CustomCursor代码:

代码语言:javascript
复制
import './CustomCursor.scss';

export default function CustomCursor(props) {

    const { x, y } = props;

    return (
        <div className='custom-cursor' style={{ left: `${x - 64}px`, top: `${y + 50}px` }} />
    )
}

当我第一次创建OnMouseMove处理程序函数时,我只需将xy状态值直接传递到它们各自的状态设置器函数中:

代码语言:javascript
复制
    function handleMouseMove(e) {
        setX(e.clientX);
        setY(e.clientY);
    }

然而,我注意到这是缓慢和滞后的,当我重构这个函数来使用setter函数时,它要快得多(我想要的):

代码语言:javascript
复制
    function handleMouseMove(e) {
        setX(prevState => { return e.clientX });
        setY(prevState => { return e.clientY });
    }

在此之前:

之后:

为什么使用setter函数比直接传递值更快?

EN

回答 1

Stack Overflow用户

发布于 2022-04-25 07:04:36

这很有趣。首先,我们需要关注状态更新的反应方式。在react https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous的文档中可以看到:React可以将多个setState()调用批处理到单个更新中以提高性能。因为this.props和this.state可能是异步更新的,所以不应该依赖它们的值来计算下一个状态。例如,此代码可能无法更新计数器:

代码语言:javascript
复制
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

要修复它,请使用接受函数而不是对象的第二种形式的()。该函数将接收前一个状态作为第一个参数,并在应用更新时将支持作为第二个参数:

代码语言:javascript
复制
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

关于这一点的一篇很好的文章是由Jan在这里写的:https://medium.com/@jan.hesters/updater-functions-in-reacts-setstate-63c7c162b16a

这里还有更多的细节:https://learn.co/lessons/react-updating-state

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71990720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档