性能优化
勾选变色
我们先用传统写法来完成勾选变色的功能,会使用到父子组件间的正传、逆传。
在判 " 勾选的是谁 " 时,思路是这样的:先是父组件正传一个函数给子组件,子组件将同时传过来的数组里某个对象的index绑定给父组件传过来的函数,然后在父组件的函数体里面通过子组件反传的变量index判断当前需要改变的元素是数组里面的哪个元素,然后改变该元素的style值。
当然,真正的dom元素样式改变是在子组件里面,通过判断父组件正传过来的style的值为true就变色,为false就不变色。
>>Check1.jsx --- 父
import React, { Component } from 'react'
import Check2 from "./check2.jsx"
export default class check2 extends Component {
constructor(props){
super(props)
this.state={
arr:[
{name:"路飞",style:false},
{name:"呢子扣",style:false},
{name:"炭治郎",style:false},
]
}
}
fun=(num)=>{
//console.log(num);//找到勾选的是谁
let newarr=this.state.arr;
newarr[num].style=!newarr[num].style;
this.setState({
arr:newarr
})
}
list=()=>{
// 不在render里写,避免污染
return this.state.arr.map((item,index)=>{
return(
<Check2 key={index} name={item.name} style={item.style} num={index} listfun={this.fun} />
)
})
}
render() {
return (
<div>
<h4>I' check1 as a father.</h4>
{this.list()}
</div>
)
}
}
>>Check2.jsx---子
import React, { Component } from 'react'
export default class check2 extends Component {
render() {
let {name,style,num,listfun}=this.props;
//console.log("我是子组件");
return (
<div style={{color:style?"red":""}}>
<input type="checkbox" onChange={listfun.bind(this,num)}/> {/*逆向传值*/}
<span>{name}</span>
</div>
)
}
}
有没有发现一个问题:
咱们在子组件的render中添加一个输出,发现每次运行的时候子组件都被调用了多次。为什么会这样?
原因是我们在更新数据的时候,使用setState修改整个数据,而当数据变了,在遍历的时候所有内容都要被重新渲染。
如果数据数量少还好,如果遍历出来的数据很多,就会严重影响性能。
做项目时尽量避免这种逆传。
那有没有什么解决方案呢?整理了三种。
提高性能–方案1
使用生命周期的钩子:
shouldComponentUpdate(nextProps,nextState) // 判定组件是否要更新
//nextProps---最新的props ; nextState---最新的state
运行之后发现可以减少不必要的渲染,提高性能。
提高性能–方案2
纯组件(PureComponent)— 类组件中使用。
PureComponent
是优化react应用程序最重要的方法。组件发生更新时,组件的props和state没有改变,render方法就不会触发 。可以减少不必要的render次数,提高性能。
省去虚拟dom生成和对比的过程,其实就是react自动帮忙做了一个浅比较(它只比较props和state的内存地址,如果内存地址相同,则shouldComponentUpdate生命周期就返回false。)
提高性能–方案3
React.memo()
— 无状态组件中使用。
类似于PureComponent,不过React.memo是函数/无状态组件,React.PureComponent是类组件。
memo依然是一种对象的浅比较。
修改react脚手架端口
react脚手架端口号:默认是3000
修改路径:
当前项目路径/node_modules/react-scripts/scripts/start.js
改端口:
onst DEFAULT_PORT = parseInt(process.env.PORT, 10) || 5000(你要修改的端口);
怎么知道项目是如何启动的
为什么create-react-app的启动命令是 npm start?和vue不一样?
怎么知道启动项目的方法?
找到项目中的 package.json文件找到 scripts属性:
大家发现是start,那么启动命令就是 npm run start / npm start(只有是start的时候可以省略run 别的不行)
修改之后 那么启动项目就必须是 npm run dev 。
项目中遇到的问题
在react脚手架中使用 confirm 有时会报错,原因是 eslint 屏蔽了这个方法。
解决方式:使用 // eslint-disable-next-line
这句注解js语句,就不用进行eslint语法检查了。
Eslint:脚手架中默认安装了,但是建议在没有特殊需求的情况下不要去配置,以免不小心修改其他配置内容。
总结
一、为了解决上面这种消耗性能的情况,然后为了提高性能, 3种解决方式:
1、钩子 shouldComponentUpdate(nextProps,nextState)
2、纯组件 PureComponent
3、无状态组件中使用的性能优化 React.memo()
二、在react项目中,如果想改变端口号,可以在/node_modules/react-scripts/scripts/start.js中进行修改。
三、// eslint-disable-next-line 可以让下面一句取消eslint验证。
四、react脚手架中,通过 npm start 或者 npm run start 启动项目,不是所有命令都可以通过 npm 命令名 来实现。