blog/React开发中提升幸福度的一些小技巧.md

第一道菜:回锅肉

react数组循环,基本都会设置一个唯一的key,表格的对象数组循环一般没什么问题,数据基本都会有一个id。那有种情况就比较坑了,出现在表单形式的页面结构中,对某个数组进行增删改操作,一般对于非对象数组而言,没有id,可能很多人会偷懒,循环的时候,直接设置数组的下标index作为key,当出现增删改时候,就会出现数据对不上或者重新渲染组件的问题等。解决方案有很多种,例如把字符串数组等重组对象数组,每个元素设置一个唯一id等。另外有个方式:推荐使用shortid生成唯一key的数组,和数据数组一起使用,省去提交数据时再重组数组。

importReactfrom'react';importshortidfrom'shortid';classDemoextendsReact.Component{constructor(props) {super(props);this.state={data:['a','b','c']}this.dataKeys=this.state.data.map(v=>shortid.generate());}deleteOne=index=>{//删除操作const{data}=this.state;this.setState({ data:data.filter((v,i)=>i!==index) });this.dataKyes.splice(index,1);    }render() {return(

    {data.map((v,i)=>this.deleteOne(i)}                          key={this.dataKeys[i]}>{v})              }
)}}//稍微抽取,可以封装一个通用的组件

第二道菜:番茄炒蛋

通过判断值是否存在来控制元素是否显示,一般三目运算可以达到此效果,最简单的还是用短路的写法:

//不错constflag='something';flag&&

//很好//注意一般可能上面写法多一些,但当flag为0 的时页面上会显示0,用!!将其转为boolean避免坑,//代码也更规范constflag='something';!!flag&&

第三道菜:酸辣土豆丝

使用组件,传递props:

const{data,type,something}=this.state;

也许另外一种传递方式更简洁:

const { data, type, something } = this.state;

    {...{ data, id, something }}

/>

第四道菜:清炒时蔬

组件的props有时候会定义很多,但是调用组件传递props的时候又想一个个传,不想一次性传递一个option对象,通过扩展运算符和解构赋值可以简化此操作:

const Demo = ({ prop1, prop2, prop3, ...restProps }) => (

   

        xxxx

        { restProps.something }

   

)

// 父组件使用Demo

    prop1={xxx}

    prop2={xxx}

    something={xxx}

/>

第五道菜:小吃-糍粑

一般改变state值的一种方式:

const{data}=this.state;this.setState({ data:{...data, key:1} });

另外一种可以通过callback的方式改变state的值

this.setState(({ data })=>({ data:{...data, key:1} }));

还可以:

this.setState((state,props)=>{return{ counter:state.counter+props.step};});

第六道菜:水煮肉片

React 性能优化有很多种方式,那常见的一种就是在生命周期函数shouldComponentUpdate里面判断某些值或属性来控制组件是否重新再次渲染。

判断一般的字符串,数字或者基础的对象,数组都还是比较好处理,那嵌套的对象或者数组就比较麻烦了,对于这种,可以转成字符串处理,但属性值的位置不同时,那就无效了。

推荐使用lodash(或者其他的类似库)的isEqual对嵌套数组或对象进行判断(相比其他方式更简单些)

shouldComponentUpdate(nextProps,nextState) {if(_.isEqual(nextState.columns,this.state.columns))returnfalse;returntrue;}

第七道菜:干锅兔

创建弹层的三种方式:

普通组件通过state和样式控制,在当前组件中显示弹层-每次引入组件并且render里面控制显示,挂载节点在某组件里面

//弹层constDialog=()=>

弹层
//某组件render() {return(this.state.showDialog&&)}

2.通过Portals创建通道,在根节点外部挂载组件-但还是需要每次引入并且在render里面调用

//弹层classDialogextendsReact.Component{constructor(props) {super(props);this.el=document.createElement('div');  }componentDidMount() {modalRoot.appendChild(this.el);  }componentWillUnmount() {modalRoot.removeChild(this.el);  }render() {returnReactDOM.createPortal(this.props.children||

xxxx
,this.el,    );  }}//某组件render() {return(this.state.showDialog&&)}

3.推荐使用ReactDom.render创建弹层-挂载根节点外层,使用也更方便

//demoletdialog;classDialog{show(children) {//显示this.div=document.createElement('div');document.body.appendChild(this.div);ReactDom.render(children||

xxxx
,this.div);    }destroy() {//销毁ReactDom.unmountComponentAtNode(this.div);this.div.parentNode.removeChild(this.div);    }}exportdefault{show:function(children) {        dialog=newDialog();dialog.show(children);    },    hide:xxxxx};//某组件importDialogfrom'xxx';alert=()=>{Dialog.show(xxxx);}render() {return()}

第八道菜:火烧肉

render props是现在很流行的一种渲染方式,通过回调函数,渲染子组件,参数可为父组件的任意属性值(官网也有相应的介绍)新版的contextApi也采用了这个模式。

很多种场景使用此方式的做法:

//权限控制组件,只需要封装一次connect,//通过render props向子组件传递权限classAuthWidgetextendsComponent{render() {returnthis.props.children(this.props.auth);    }}constmapStateToProps=state=>{const{auth}=state;return{ auth:state.auth};};exportdefaultconnect(mapStateToProps)(AuthWidget);//其他组件使用auth.edit&&编辑}/>//使用antd的form时constTest=({ form, children })=>{returnchildren(form);};constFormTest=Form.create()(Test);classDemoextendsComponent{render() {return(

xxxxx{form=>{this.form=form;return(
{getFieldDecorator('field', xxx)()}
)                    }}
)    }}

第九道菜:粉丝白菜虾仁汤

子组件改变父组件的state方式有很多种,可以在父组件设置一个通用函数,类似:setParentState,通过子组件回调处理时,就可以更方便的统一处理:

//父组件state={    data:{}}setParentState=obj=>{this.setState(obj);}//子组件onClick=()=>{this.props.setParentState({ data:xxx });}

第十道菜:麻婆豆腐

永远不要直接设置state的值:this.state.data = { a: 1 }。这个会导致几个问题: 1:组件不会重新渲染 2:shouldComponentUpdate(nextProps, nextState) 函数里面 this.state的值是已经改变了,和nextState的值相同。

举个栗子:

// wrong

const { data } = this.state;

data.a = 1;    // 等价于this.state.data.a = 1;

this.setState({ data }); // shouldComponentUpdate里面观察到 this.state 和nextState的值是相同的

// 此时函数里面性能相关的优化是无效的

// correct  需要用到当前state值的写法

this.setState(state => ({ data: {...state.data, a: 1} }))

如果想学习Java工程化、高性能及分布式、深入浅出。性能调优、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级程序员群:180705916,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

你可能感兴趣的:(blog/React开发中提升幸福度的一些小技巧.md)