Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何使用React.memo优化性能_Reactjs_React Hooks - Fatal编程技术网

Reactjs 如何使用React.memo优化性能

Reactjs 如何使用React.memo优化性能,reactjs,react-hooks,Reactjs,React Hooks,我用React前端下了一盘棋。最初,任何移动似乎都是瞬间实现的,但在添加了额外的功能后,例如更改标题的背景以反映轮到谁(白色或黑色背景取决于其白色的移动)和其他类似功能,我的应用程序明显变慢了。我怀疑是这些类型的if语句- const Details = props => { console.log(props.status); let [backGround, setBackGround] = useState("w details") con

我用React前端下了一盘棋。最初,任何移动似乎都是瞬间实现的,但在添加了额外的功能后,例如更改标题的背景以反映轮到谁(白色或黑色背景取决于其白色的移动)和其他类似功能,我的应用程序明显变慢了。我怀疑是这些类型的if语句-

const Details = props => {
    console.log(props.status);
    let [backGround, setBackGround] = useState("w details")
    const history = useHistory();

    if (props.status.white && backGround === "bl details"){
        setBackGround("w details")
    } else if (!props.status.white && backGround === "w details"){
        setBackGround("bl details")
    }
这是因为打印道具的console.log每次移动将打印其语句8次(最初是两次)

我使用的是功能组件而不是类,我对优化的研究使我找到了以下解决方案-

所有这些都指向了React.memo的简单例子,但我显然遗漏了一些东西,因为当我试图实现它时,我得到的只是大量未定义的“道具”错误(我每次使用道具都有一个,这是非常多的)

详细信息。jsx

import React, { useState } from 'react';
import "../App.css"
import DataService from '../service/DataService';
import { useHistory } from 'react-router-dom';

let [backGround, setBackGround] = useState("w details")
const Details = React.memo(props => {if (props.status.white){setBackGround("w details")} else {setBackGround("bl details")}}, (prevProps, props) => prevProps.white === props.white);  {
    console.log(props.status);
    
    const history = useHistory();

    const undo = () => {
        DataService.undo()
        .then(res => {
            console.log(res);
            props.setTheBoard(res.data);
            props.changeTurn();
        })
        .catch(err => {
            console.log(err);
            window.alert(err.response.data.errMessage)
        })
    }
    
    const restart = () => {
        DataService.restartGame()
        .then(res => {
            console.log(res);
            props.setTheBoard(res.data);
            props.changeTurn(true);
        })
        .catch(err => {
            console.log(err);
            window.alert(err.response.data.errMessage)
        })
    }

    const newGame = () => {
        history.push('/');
    }

    return ( 
        <div className={backGround} >  
            {props.status.active ? <h2>It is {props.status.playerName}'s turn</h2> :
            <div>           
                <h1 className="check">Game Over!</h1>
                <button className="tooltip" onClick={restart}>RESTART<span className="tooltiptext">Play another game vs the same opponent</span></button>
                <button className="tooltip" onClick={newGame}>NEW GAME<span className="tooltiptext">Play a game vs a different opponent</span></button>
            </div>}                          
                       
                           
            {props.status.active &&
            <div>                
                {props.isMove ? <button className="detailButtons" onClick={props.specialMove}>Special Move</button> : <button className="detailButtons" onClick={() => props.endTheGame(true)}>Forfeit</button> }
                {props.isMove ? <button className="detailButtons" onClick={props.unselect}>Unselect Piece</button> : <button className="detailButtons" onClick={() => props.endTheGame(false)}>Draw</button> } 
                {props.isMove ? <button className="detailButtons">Toggle Sidebar</button> : props.undo && <button className="detailButtons" onClick={() => undo()}>Undo</button> }                
                {props.status.check && <h1 className="check">You must move out of check!</h1>}                
            </div> }
            
        </div>
     );
}
 
export default Details;
import React,{useState}来自“React”;
导入“./App.css”
从“../service/DataService”导入数据服务;
从'react router dom'导入{useHistory};
let[背景,挫折]=useState(“w细节”)
const Details=React.memo(props=>{if(props.status.white){setBackGround(“w Details”)}else{setBackGround(“bl Details”)},(prevProps,props)=>prevProps.white==props.white);{
控制台日志(道具状态);
const history=useHistory();
常量撤消=()=>{
DataService.undo()
。然后(res=>{
控制台日志(res);
道具设置板(res.data);
props.changeTurn();
})
.catch(错误=>{
控制台日志(err);
window.alert(err.response.data.errMessage)
})
}
常量重新启动=()=>{
DataService.restartGame()
。然后(res=>{
控制台日志(res);
道具设置板(res.data);
道具。改变方向(真);
})
.catch(错误=>{
控制台日志(err);
window.alert(err.response.data.errMessage)
})
}
const newGame=()=>{
历史推送(“/”);
}
报税表(
{props.status.active?轮到{props.status.playerName}了:
游戏结束!
重新开始与同一对手进行另一场比赛
新游戏对不同对手的游戏
}                          
{props.status.active&&
{props.isMove?特殊移动:props.endTheGame(true)}>放弃}
{props.isMove?取消选择棋子:props.endTheGame(false)}>平局}
{props.isMove?切换侧栏:props.undo&&undo()}>undo}
{props.status.check&&您必须退出检查!}
}
);
}
导出默认详细信息;
由于此组件中的道具仅在回合更改时更改(props.status.white),因此我认为这将是一个减少不必要的重新渲染的好地方,但我看到的所有解决方案都非常简单。当像这样的道具被广泛使用时,是否可以使用React.memo


如何在保持对道具的访问的同时优化性能?

首先,关于在前端测试性能,您必须记住一点

当您在devtools中检查性能、活动时,决不会让devtools保持打开状态,这会大大降低应用程序的性能

其次,
useMemo
useCallback
都不会给您带来任何性能改进,如果您没有完全渲染,渲染之前可能渲染过的道具,最重要的是,如果您没有在自定义组件中渲染其他自定义组件,那么您可能也不需要使用这些挂钩

那么,我们应该在哪种情况下使用
useCallback
usemo
,以提高性能

在回答这个问题之前,您应该知道值类型和引用类型之间的区别

值类型是不可变的,所以您可以安全地分配、修改和使用它,而不必担心所有权和垃圾收集器

JS中的原语文本类型是值类型:

让a=“你好” 设b=a //从这里开始,b不拥有引用,因为a是一种值类型 设c=新字符串(“Hello”) 设d=c //现在d拥有c引用,因为c被初始化为String类的实例 这是一个非常简单的示例,说明了如何使用两种不同的方法创建相同的字符串

第一个是使用文本字符串创建字符串。 第二,使用String类的实例

如果我们这样做:

a==b//true
==
a
值与
b
中的值进行比较

然而,当我们这样做时,会发生一些不同的事情:

c==d//true
这也会返回
true
,但是
=
在这里的工作方式不同,它不是比较值,而是比较c的参考严格等于d的参考。如果仅使用
==
运算符,
c
的值严格等于
d
的值,我们无法进行比较,因为两者都是字符串的引用类型,我们应该这样比较:

//toString()在本例中同样有效,但valueOf在本例中更具语义
c、 valueOf()==d.valueOf())
想想
a
b
不指向内存中的引用,而是
d
引用
c
中创建的相同的引用

现在,考虑到这一点,让我们回到过去