一、引言

通过这周需要的开发,我发现自己在编写代码的过程中不太关注代码的复用性和可维护性,不经意间就间接简略的复制粘贴就完事,这样看起来是实现了性能,然而却为当前的开发留下了很大的隐患。所以,这周我顺便联合了本人开发过程中的问题,简略了理解了一下对于进步React代码复用性的两种办法。

二、应用React高阶组件来晋升代码的可复用性

先介绍一下什么是React的高阶组件,

高阶组件是一个函数,接管一个组件,而后返回一个新的组件。

const EnhancedComponent = highOrderComponent(WrappedComponent);

要记住的是,尽管名称是高阶组件,然而高阶组件不是组件,而是函数

既然是函数,那就能够有参数,有返回值。从下面能够看出,这个函数接管一个组件WrappedComponent作为参数 ,返回加工过的新组件EnhancedComponent。其实高阶组件就是设计模式里的装璜者模式。

能够说,组件是把 props 转化成 UI,而高阶组件是把一个组件转化成另外一个组件。

上面是一个简略的高阶组件:

import React, { Component } from 'react';export default (WrappedComponent) => {  return class EnhancedComponent extends Component {    // do something    render() {      return <WrappedComponent />;        //HOC返回的是一个新的组件    }  }}

其实,这只是其中的一种高阶组件,这个时候高阶组件复用的是组件,也就是说在一个通用的组件中增加额定的逻辑,而后返回一个增加了额定办法和参数的新组件

另外一种高阶组件复用的是多个组件中雷同的逻辑,返回一个新的组件。我在开发中应用到的就是这种模式的高阶组件。它是这样的模式:

//组件一class Component1 extends React.Component {  ...}  //组件二class Component2 extends React.Component {  ...}  //假如组件一和组件二都须要应用雷同的函数foo//设计一个能够复用foo的高阶组件const HOCComponent = (Component, props) => {    const obj = {        foo1() {},        foo2() {},        ...     //这里示意想增加的其余参数    };        const newprops = Object.assign({}, obj, props);    return <Component {...newprops}/>}//应用该高阶组件let newComponent1 = HOCComponent(Component1, this.props);let newComponent2 = HOCComponent(Component2, this.props);

这样就能够实现复用两个组件雷同的函数或者其余的参数了,不必在每个组件中都写反复的代码。

三、应用React Hook:useState()来晋升代码的可复用性

先简略介绍一下useState这个hook,

用法:

const [state, setState] = useState(initialState);

返回值:state,更新state的函数setState

参数:初始的state:initialState

因为useState这个Hook诞生之前,如果想应用state必须得定义类组件,函数组件无奈应用state,然而组件的演变必定是往轻量化这个方向演变的,所以useState就能够是函数组件也能够应用state。

来看一下上面这个例子:

有一个这样的场景:

当初有 小A,小B 两位同学,每位同学都处于未穿鞋的状态,小A穿鞋须要2s,小B穿鞋须要5s,在页面一中用文字描述两位同学的穿鞋状态变更( 如果小A正在穿鞋中,则在页面上显示 '小A正在穿鞋子',如果小A曾经穿好了鞋子,则将文字替换为 '小A曾经穿好鞋子')

应用class组件实现是这样的:

 import React from "react";  class Page extends React.Component {   state = {     data: [       { id: 1, name: "小A", time: "2000" },       { id: 2, name: "小B", time: "5000" }     ]   };    start(item) {     this.setState({       [item.id]: "穿鞋子"     });      setTimeout(() => {       this.setState({         [item.id]: "穿好鞋子"       });     }, item.time);   }    componentDidMount() {     this.state.data.forEach(item => {       this.start(item);     });   }    render() {     return (       <div>         {this.state.data.map(item => {           return (             <h1 key={item.id}>               {this.state[item.id] === "穿鞋子"                 ? `${item.name}正在穿鞋子...`                 : `${item.name}曾经穿好鞋子了`}             </h1>           );         })}       </div>     );   } }  export default Page;

应用Hook组件实现是这样的

自定义Hook如下:

  • src/useHook.js
import React, { useState } from "react";  function useHook(item) {   const [status, setStatus] = useState("穿鞋子");    setTimeout(() => {     setStatus("穿好鞋子");   }, item.time);    return (     <h1 key={item.id}>       {status === "穿鞋子"         ? `${item.name}正在穿鞋子...`         : `${item.name}曾经穿好鞋子了`}     </h1>   ); }  export default useHook;

援用hook的函数组件

  • src/hookDemo1.js
 import React from "react"; import useHook from "./useHook";  function Page() {   const data = [     { id: 1, name: "小A", time: "2000" },     { id: 2, name: "小B", time: "5000" }   ];   return (     <div>       {data.map(item => {         return useHook(item);       })}     </div>   ); }  export default Page;

看起来并没有什么区别嘛,代码量也没有缩小。

然而,如果小C和小D也要实现这样的形容,应用定义好的Hook就简略多了。

  • src/hookDemo2.js
 import React from "react"; import useHook from "./useHook";  function Page() {   const data = [     { id: 1, name: "小C", time: "4000" },     { id: 2, name: "小D", time: "8000" }   ];   return (     <div style={{ color: "lightblue" }}>       {data.map(item => {         return useHook(item);       })}     </div>   ); }  export default Page;