redux-form性能优化

最近项目中使用redux-form遇上性能瓶颈,

需要100行以上联动表单变得极其卡

原因

  • 组件过多渲染导致! 更改一个输入框导致所有输入框都重新渲染。

解决思路

  • Field 使用 PureComponent 减少不必要的渲染[如果无效用shouldComponentUpdate ]

  • 推荐使用shouldComponentUpdate 精确控制到每行及每个输入框的渲染

  • 覆盖掉redux-from的onChange事件 改用onFocus和onBlur

下面代码我在FormMembers里遍历了fields,所以FormMembers重新渲染时会导致fields全部重新渲染。

优化后使用shouldComponentUpdate控制到每一行及每一个输入框的重新渲染,提高了非常多的性能!

优化前代码及结构

//表单
class Form extends Component{
	render() {
		return (
			<div>
				<form onSubmit={()=>{}}>
					<table className="recipe_table" >
					<FieldArray
						name="members"
						recipeName="herbal"
						component={FormMembers}
						change={change}
						public_expense={public_expense}
					/>
					</table>
				</form>
			</div>)
	}
}
//Members
class FormMembers extends Component{
	render() {
		let {fields}=this.props;
		return(
		<tbody>
		{fields.map((item,key)=>{
			console.log('//此处省略大量计算')
			return (
				<tr key={key} >
					<td>
					<Field name={`${item}.name`} component={Field}/>
					</td>
				</tr>
				)
		})}
		</tbody>)
	}
}
//数字输入框
class Field extends Component{
	render(){
		let {input}=this.props;
		return <input {...input} />
	}
}
复制代码

优化后

import isEqual from "lodash/isEqual";
//表单
class Form extends Component{
	render() {
		return (
			<div>
				<form onSubmit={()=>{}}>
					<table className="recipe_table" >
					<FieldArray
						name="members"
						recipeName="herbal"
						component={FormMembers}
						change={change}
						public_expense={public_expense}
					/>
					</table>
				</form>
			</div>)
	}
}

//Members
class FormMembers extends Component{
	render() {
		let {fields}=this.props;
		return(
		<tbody>
		{fields.map((item,key)=>(<Line item={item} lineKey={key} />))}
		</tbody>)
	}
}

//每行刷新控制
class Line extends Component{
	constructor(props){
		super(props)
		this.currData={};
	}
	shouldComponentUpdate(nextProps,nextState){//改用手动控制每行渲染
		if(!isEqual(nextProps.fields.get(nextProps.lineKey),this.currData)){
			return true;
		}
		return false;
	}
	render(){
		this.currData=this.props.get(this.props.lineKey)
		console.log('//此处省略大量计算')
		return (
			<tr key={this.props.lineKey} >
				<td>
				<Field name={`${item}.name`} component={Field}/>
				</td>
			</tr>)
	}
}

//数字输入框
class Field extends Component{
	shouldComponentUpdate(nextProps, nextState){//改用手动控制渲染
		if(nextProps.input.name==this.props.input.name && 
			nextProps.input.value==this.props.input.value && 
			nextProps.className==this.props.className  &&
			nextProps.id==this.props.id &&
			isEqual(nextProps.meta,this.props.meta)){
			return false
		}
		return true
	}
	render(){
		let {input}=this.props;
		return <input {...input} />
	}
}
复制代码

建议使用 reselect 优化性能

github.com/reactjs/res…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值