redux-form性能優化

最近項目中使用redux-form趕上性能瓶頸,react

須要100行以上聯動表單變得極其卡git

緣由

  • 組件過多渲染致使! 更改一個輸入框致使全部輸入框都從新渲染。

解決思路

  • Field 使用 PureComponent 減小沒必要要的渲染[若是無效用shouldComponentUpdate ]github

  • 推薦使用shouldComponentUpdate 精確控制到每行及每一個輸入框的渲染redux

  • 覆蓋掉redux-from的onChange事件 改用onFocus和onBlurbash

下面代碼我在FormMembers裏遍歷了fields,因此FormMembers從新渲染時會致使fields所有從新渲染。性能

優化後使用shouldComponentUpdate控制到每一行及每個輸入框的從新渲染,提升了很是多的性能!優化

優化前代碼及結構ui

//表單
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} />
	}
}
複製代碼

優化後this

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…spa

相關文章
相關標籤/搜索