奥利奥-react.js高级用法

1. 高阶组件

定义

把组件作为参数,并返回(高阶)组件的函数,称为高阶组件

优点
  • 代码复⽤,状态/逻辑抽象
  • 可以对 state/event/props 进⾏劫持、操作
使用案例

假如有这样的场景,两个查询列表的⻚⾯结构相同,查询条件相同,只是表头包括操作列不⼀样:
场景图

显然这两个⻚⾯具有很⾼的复⽤性,不只是 UI 级别的复⽤,逻辑都⼏乎⼀致,这时候,⾼阶组件就派上⽤场了。我们定义查询条件的部分为组件 SearchPanel,
表格组件为 Table(antd design 的 Table ⾃带 底部分⻚区),那么这两个⻚⾯可能是下⾯的代码结构:
⻚⾯ 1,可能是普通⽤户查看⻚

import React, { Component } from 'react';
import request from 'axios';
import { Button, Table } from 'antd';
import SearchPanel from './SearchPanel';

export default class Page1 extends Component {
  state = {
    query: {
      name: '',
      id: '',
      time: '',
      valid: ''
    },
    dataSource: []
  }
  columns = [
    {dataIndex: 'label', title: '标签'},
    {dataIndex: 'action', title: '操作',
      render: (_, record) => {
        const onOpen = () => window.open(`/xxx/${record.id}`);
        return <Button onClick={onOpen}>查看</Button>;
      }
    }]

  onChange = (params) => {
    this.setState(query => ({ ...query, ...params }));
    request('/api/list', {
      method: 'GET',
      params
    }).then(res => { // 这⾥暂不考虑异常
      this.setState({ dataSource: res.data });
    });
  }

  componentDidMount() {
    this.onChange(this.state.query);
  }

  render() {
    const { query, dataSource } = this.state;
    return (
      <>
        <SearchPanel value={query} onChange={this.onChange} />
        <Table columns={this.columns} dataSource={dataSource} />
      </>
    );
  }
}

⻚⾯ 2,可能是管理员⻚⾯

import React, { Component } from 'react';
import request from 'axios';
import { Button, Table } from 'antd';
import SearchPanel from './SearchPanel';

export default class Page2 extends Component {
  state = {
    query: {
      name: '',
      id: '',
      time: '',
      valid: ''
    },
    dataSource: []
  }

  onEdit = id => {}
  onDelete = id => {}

  columns = [
    {dataIndex: 'name', title: '名称'},
    {dataIndex: 'action', title: '操作',
      render: (_, record) => {
        return <>
          <Button onClick={() => this.onEdit(record.id)}>编辑</Button>
          <Button onClick={() => this.onDelete(record.id)}>删除</Button>
        </>;
      }
    }]

  onChange = (params) => {
    this.setState(query => ({ ...query, ...params }));
    request('/api/list/admin', {
      method: 'GET',
      params
    }).then(res => { // 这⾥暂不考虑异常
      this.setState({ dataSource: res.data });
    });
  }

  componentDidMount() {
    this.onChange(this.state.query);
  }

  render() {
    const { query, dataSource } = this.state;
    return (
      <>
        <SearchPanel value={query} onChange={this.onChange} />
        <Table columns={this.columns} dataSource={dataSource} />
      </>
    );
  }
}

可以看到,两份代码除了表格列及其操作外,请求数据的接⼝也分别为 /api/list 和 /api/list/admin,这两份⽂件总计约 100 ⾏代码。我们使⽤⾼阶组件整合相同的逻辑:
Page1 和 Page2 的公共 UI 部分:

import React from 'react';
import { Table } from 'antd';
import SearchPanel from './SearchPanel';

// ⽆状态组件,所以⽤函数实现更简洁
export default function PageCommon({ query, dataSource, onChange, columns }) {
  return (
    <>
      <SearchPanel value={query} onChange={onChange} />
      <Table columns={columns} dataSource={dataSource} />
    </>
  );
}

⾼阶组件:

import React, { Component } from 'react';
import request from 'axios';

export default function hoc(WrappedComponent, api) {
  return class extends Component {
    state = {
      query: {
        name: '',
        id: '',
        time: '',
        valid: ''
      },
      dataSource: []
    }

    onChange = (params) => {
      this.setState(query => ({ ...query, ...params }));
      request(api, {
        method: 'GET',
        params
      }).then(res => { // 这⾥暂不考虑异常
        this.setState({ dataSource: res.data });
      })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值