美文网首页
React基础5:组件设计模式

React基础5:组件设计模式

作者: CC前端手记 | 来源:发表于2020-06-24 11:20 被阅读0次

    React有这样两种组件设计模式,高阶组件和函数式组件。高阶组件是将需要复用的逻辑提取到一个函数中,再去处理不同组件。函数作为子组件,是使用子组件来复用逻辑,然后从父组件传入不同内容。
    我们来看下如何使用:

    一、高阶组件

    高阶组件是一个函数,它接受一个组件,返回一个新组件,可以提供可复用的功能。使用方法见下图:

    // withToolTip.js
    import React from 'react'
    const withToolTip = (Component) => {
      class HOC extends React.Component {
        state= {
          showToolTip: false,
          content: ''
        }
        handleOver =(ev)=> this.setState({showToolTip: true, content: ev.target.innerText})
        handleOut = (ev)=> this.setState({showToolTip: false, content: ''})
        render(){
          return (
            <div onMouseOver={this.handleOver} onMouseOut={this.handleOut}>
              <Component action={this.state} />
            </div>
          )
        }
      }
      return HOC
    }
    export default withToolTip;
    
    // ItemA.jsx
    import React, {Component} from 'react';
    import withToolTip from './withToolTip'
    const ItemA = (props) => {
      return (
        <div>
          <button type="btn">ToolTipA</button>
          {props.action.showToolTip && (
            <span>
              {props.action.content}
            </span>
          )}
        </div>
      )
    }
    export default withToolTip(ItemA);
    
    // ItemB.jsx
    import React, { Component } from 'react';
    import withToolTip from './withToolTip';
    const ItemA = (props) => {
      return (
        <div>
          <button type="btn">ToolTipB</button>
          {props.action.showToolTip && (
            <span>
              {props.action.content}
            </span>
          )}
        </div>
      )
    }
    export default withToolTip(ItemB);
    
    // App.js
    import React, {PureComponent} from 'react';
    import ItemA from './component/hoc/itemA';
    import ItemB from './component/hoc/itemB';
    class App extends PureComponent {
      constructor(props){
        super(props);
        this.state = {
          listData: [
            {
              id: 1,
              name: 'name1'
            },
            {
              id: 2,
              name: 'name2'
            }
          ]
        }
        ...
      }
      render(){
        return (
          <>
            <ItemA />
            <ItemB />
          </>
        )
      }
    }
    export default App;
    

    总结一下例子中的基本用法:

    1. 父组件App引入两个子组件——ItemA和ItemB。
    2. ItemA和ItemB分别import withToolTip,并将组件ItemA/B作为参数返回新函数withToolTip(ItemA/B)。
    3. 将可复用的功能写在withToolTip函数中:定义方法名为withToolTip,将Component作为参数,返回withToolTip方法。在方法内部,定义类组件HOC并返回。在类组件HOC中定义state和渲染组件。

    二、函数作为子组件

    函数作为子组件,是使用子组件处理复用逻辑,然后从父组件传入不同内容。基本用法是:

    1. 定义子组件:
    render(){
      return (
        <div>{this.props.render(this.state)}</div>
      )
    }
    
    1. 使用函数作为Props
    <RenderPropComponent render = { (state)=>(
      <div>content</div>
    )} />
    

    接下来,我们将上文高阶组件的例子改造成函数作为子组件的使用方式:

    1. withToolTip.js文件中,去掉const withToolTip = (Component) => {}一层;并且将<Component action={this.state} />替换为{this.props.render(this.state)}
    2. 新建ItemC.jsx组件,这里和ItemA/B的区别主要是:
      在组件内,直接使用withToolTip组件,并将页面结构放在render中;
      将props.action.xxx的props.action去掉;
      直接返回ItemC组件。
    import React, {Component} from 'react';
    import withToolTip from './withToolTip';
    const ItemC = (props) => {
      return (
        <div>
          <WithToolTip render= {
              <div>
                <button type="btn">ToolTipA</button>
                {showToolTip && (
                  <span>{content}</span>
                )}
              </div>
          } />
        </div>
      );
    }
    export default ItemC;
    

    其中,引用<WithToolTip />组件部分,也可以使用下面的写法:

    <WithToolTip>
      { (showToolTip, content)=>(
        <div>
          <button type="btn">ToolTipA</button>
          {showToolTip && (
             <span>{content}</span>
          )}
        </div>
    ) }
    </WithToolTip>
    
    1. withToolTip.js文件修改,也要去掉const withToolTip=(Component)=>{}一层,将HOC改为WithToolTip;去掉return HOC;并且将withToolTip大写,如下:
    import React from 'react'
    class WithToolTip extends React.Component {
        state= {
          showToolTip: false,
          content: ''
        }
        handleOver =(ev)=> this.setState({showToolTip: true, content: ev.target.innerText})
        handleOut = (ev)=> this.setState({showToolTip: false, content: ''})
        render(){
          return (
            <div onMouseOver={this.handleOver} onMouseOut={this.handleOut}>
              <Component action={this.state} />
            </div>
          )
        }
    }
    export default WithToolTip;
    

    相关文章

      网友评论

          本文标题:React基础5:组件设计模式

          本文链接:https://www.haomeiwen.com/subject/lxzhfktx.html