React组件开发(心得体会)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/running_shuai/article/details/80441931
1、有状态组件和无状态组件

其实换言之就是需不需要一套react的生命周期来维护这一套状态,有时候我们提出一个子组件来,但是这个子组件除了render出来一虚拟dom结构,并没有任何状态,所以是没必要提出来做一个单独的组件,哪怕是想复用。这个时候就用到了无状态组件,即一个无状态函数,这样在渲染的时候,就省去了子组件生命周期的维护和执行,避免了不必要的检查和内存分配,做到了内部优化。

    class App extends React.Component{
        constructor(props){
            super(props);
            this.state = {}
        }
        render(){
            return <div>aaaa</div.
        }
    }
    典型的无状态无生命周期组件,所以说不管复用也好,拆分也好,这种无状态无周期组件写成一个无状态函数最完美。
    renderapp = ()=>{
        render(){
            return <div>aaaa</div.
        }
    }
2、高阶组件的使用。

高阶函数

    setFristName = ()=>{
        this.setState({visible:false})
        console.log('setFristName')
    }
    setLastName = ()=>{
        this.setState({visible:false})
        console.log('setLastName')
    }
    这两个函数this.setState({visible:false})是共有的思维,  
    可以做一个中间函数专门处理提取公有的逻辑
    setFristName = ()=>{
        let {name} = this.state
        this.setState({visible:false})
        console.log('setFristName',name)
    }
    setLastName = ()=>{
        let {name} = this.state
        this.setState({visible:false})
        console.log('setLastName',name)
    }
    commonConpute = (wrappedFunc)=>{
         let newFunc = () => {
             let {name} = this.state
            this.setState({visible:false})
            wrappedFunc(name);
        }
        return newFunc;
    }
    commonConpute(setFristName)();
    commonConpute(setLastName)()

高阶组件的使用就是类似于高阶函数的思想来创建一个中间函数,做函数传递

import React, {Component} from 'react'
CommonConpute = (SetLastName) => {
    class NewCommonComponent extends Component {
        constructor(props) {
            super(props);
            this.state = {
               name: ''
            }
        }
        componentWillMount() {
            let name = localStorage.getItem('name');
            this.setState({name})
        }
        render() {
            return 
                <SetLastName
                    username={this.state.username}
                />
        }
    }

    return NewCommonComponent
}
export default CommonConpute
a = ()=>{
    class
    return 类名
}
export default a;
所谓的高阶组件,其实就是高阶函数对容易的封装。参数就是子组件。
import React, {Component} from 'react';
import CommonConpute from 'commonConpute.js';

class SetLastName extends Component {

    render() {
        return (
            <div>welcome {this.props.username}</div>
        )
    }
}
export default CommonConpute(SetLastName);

 高阶组件就是用一个高阶函数把子组件当作参数传递给目标组件了。  
 目标组件使用子组件的时候把name 通过 props 传递给子组件了。 
 子组件只管从 props里面拿来用就好了。
3、组件模块化思想

使用React时,组件或容器的代码在根本上必须只负责一块UI功能。不管是无状态组件函数,还是有状态组件模块,都应该是负责ui界面的一整块的功能。所以在划分组件和拆分的时候一定要规划好。

    不规范展示Viw
    <div>
        <Header/>
        <ul>
            {
                this.state.schoolList.splice(0,2)  
                             .map((item,index)=>{
                        return 
                        <li key={index}>
                            {item.schoolName}
                        </li>
                })
            }
            {
                this.state.schoolList.splice(2,4)  
                             .map((item,index)=>{
                        return 
                        <li key={index}>
                            {item.schoolName}
                        </li>
                })
            }
        </ul>
        <Footer/>
    </div>
    中间UI中的列表这里,有两个{}表达式分隔开了本该是一个组件。
    分割不合理,而且this.state.schoolList.splice计算也是重复的截取。
    {
        this.state.schoolList.map((item,index)=>{
            return (
                 <li key={index}>
                    {item.schoolName}
                  </li>
                  {index == 1 ? <br/> : null}
                )
                })
    }

写到现在,其实心得有些分享一下:

  • 如果组件根本不需要状态,那么就使用函数定义的无状态组件,即函数
  • 传递组件所需要的属性。只有当属性列表太长时,才使用{…this.props}进行传递。我曾经有段时间非常喜欢这样不太合适的写法:

     class App extends React.Component{
         constructor(props){
                super(props);
                this.state = {
                    ...props
                }
            }
        }
    

    这样其实很容易造成state命名重复,很难维护和开发。所以传递的时候尽量传递需要的,

  • 如果组件里面有太多的判断逻辑(if-else语句)通常意味着这个组件需要被拆分成更细的组件或模块。
  • 模块类命名,方法命名,变量命名尽量团队统一,保持统一风格,简明扼要,见名之意,有助于组件复用和组件维护。
  • 注释,要不就别加,真的,要么整个团队要保持良好习惯,加的话,每次的迭代更新就要更改注释。最好,明白清楚,简要。团队风格统一。不要误导,千万不要误导。
  • 在shouldComponentUpdate中检查更新,是否重新render的时候,判断一定要精确,避免不必要的render,重paint,diff算法也是很耗费性能的。

4、组件开发注意点
  • 三元函数组件判断渲染,最多一层,再多的用if-elseif-else来吧,因为复杂点的三目运算可读性很差

        isTrue ? {}:isShow ? {} : {} 不可取,可读性非常差
    
  • 如果组件需要三木运算符

     {
         isTrue ? <App/>  : isShow ? <App1/> : <App2/>  
     }
     最佳的解决方案:
         将逻辑移到无状态组件内部,不同条件的时候return不同的组件。  
         这样做的好处就是把UI结构和逻辑层分开。
        return (
            {this.renderApp}
        )
        renderApp = ()=>{
            if(isTrue){
                return <App/>
            }else{
                if(isShow){
                    return <App1/>
                }else{
                    return <App2/>
                }
            }
        }
    
  • setState合并为一次更新

    在无状态函数里最好执行完毕以后一次性的setState
    setModalVisible = ()=>{
        this.setState({data:[1,2,3]})
        .....
        this.setState({arr:[2,3]})
    }
    将多次state更新合  
    并成一次更新。避免触发多次render,耗费diff性能。
    
    ⚠️:大家都知道setState是异步更新,可以在回调函数中拿到最新的state  
        值,所以setState异步执行所花费的时间完全取决于irtual DOM的  
        diff算法。
    
  • -

猜你喜欢

转载自blog.csdn.net/running_shuai/article/details/80441931