,

React 复杂组件嵌套

复杂页面:头部分页,左侧搜索,右侧表格,表格支持弹窗,弹窗里又嵌套表格 src\pages\staff\ind…

复杂页面:头部分页,左侧搜索,右侧表格,表格支持弹窗,弹窗里又嵌套表格

src\pages\staff\index.jsx

import React,{useEffect, useState} from 'react';
import { useSelector, useDispatch } from 'umi';
import TableHeader from 'components/TableHeader';
import FilterForm from './component/FilterForm';
import SearchContainer from 'components/SearchContainer';
import TableList from './component/TableList';

import './css/index.less'
const Index = () => {
    const dispatch = useDispatch();
    const [page, setPage] = useState(1);
    const {staffList, staffTotal, staffDetail, loading} = useSelector(state => state.staff);
    const { userInfo } = useSelector(state => state.user);
    
    const size = 10;
    useEffect(() => {
        _initStaffList();
    },[])

    const _initStaffList = (curPage)=>{
        dispatch(
            {
                type:'staff/initStaffList',
                payload:{
                    page: curPage || page,
                    size,
                }
            }
        );
    }
    const changePage = (curPage) => {
        console.log(curPage,'curPage');
        setPage(curPage);
        _initStaffList(curPage || page);
    }
    const interfaceDelMethod = (params) => {
        console.log(params,'params');
    }
    console.log(staffList,'staffList',staffTotal,'staffTotal',staffDetail, 'staffDetail');
    return (
        <div className="main-content">
            <TableHeader
                page={page}
                size={size}
                total={staffTotal}
                changePage={changePage}
                interfaceDelMethod={interfaceDelMethod}
            />
            <SearchContainer render={()=><FilterForm/>} />
            <TableList 
                userInfo={userInfo}
                staffList={staffList}
                loading={loading}
            />
        </div>
    );
}

export default Index;

拆分三个外层组件TableHeader、SearchContainer 、TableList

src\pages\staff\component\TableList.jsx

import React, { useState, useContext, useEffect, useRef, useCallback } from 'react';
import { Table, Form, Input } from 'antd';
import {EditableRow, EditableCell} from 'components/Editable';
import Columns from './Columns';
import Dialog from 'components/Dialog';
import RecordTable from './RecordTable';
const EditableContext = React.createContext(null);
 const dataSource = [
    {
      key: '0',
      name: 'Edward King 0',
      age: '32',
      address: 'London, Park Lane no. 0',
      auth: '管理员',
    },
    {
      key: '1',
      name: 'Edward King 1',
      age: '32',
      address: 'London, Park Lane no. 1',
      auth: '普通用户',
    }
  ];

 const handleSave = (row) => { 
    console.log(row,'handleSave');
};

const TableList = ({userInfo, staffList, loading}) => {
  const [currentRecord, setCurrentRecord] = useState(null);
  const [dialogStatus, setDialogStatus] = useState(false);
  const getDialogList = useCallback((data) => { 
    setCurrentRecord(data);
    setDialogStatus(true);
  }, []);
 const toggleDialog = () => setDialogStatus(prev => !prev);
  const updateStatus = (status)=>{
    console.log(dialogStatus,'切换弹窗');
    setDialogStatus(status);
  }
  const components = {
    body: {
      row: EditableRow,
      cell: EditableCell,
    },
  };
    return (
      <>
        <Table
          components={components}
          rowClassName={() => 'editable-row'}
          bordered
          dataSource={staffList}
          pagination={false}
          scroll = {{ x: true }}
          rowKey= {record => record._id }
          loading= {loading?.effects['staff/initStaffList']}
          columns={Columns({userInfo,handleSave, getDialogList})}
        />
        <Dialog
          title = {currentRecord?.title||''}
          dialogStatus = {dialogStatus}
          setDialogStatus = {toggleDialog}
          render={()=><RecordTable {...currentRecord} />}
        />
      </>
    );
}

export default TableList;

将表格内容拆分成2个组件Table 和 Dialog,利用antd的Table和Modal

src\pages\staff\component\RecordTable\index.jsx

import React, { useEffect, useState }  from 'react';
import $http from 'api';
import { Table } from 'antd';
import { columnData } from './renderType';
const RecordTable = (params) => {
    console.log(params,'params');
    const {title, interfaceName, requestData, type} = params;
    const [currentData, setCurrentData] = React.useState([]);
    const [total, setTotal] = useState(0);
    useEffect(() => {
       _initData();
    }, []);

    const _initData = async (page = 1,size = 5) => {
   
        const res = await $http[interfaceName]({...requestData, page,size});
        console.log(res,'_initData');
        setCurrentData(res.data.list);
        setTotal(res.data.total);
        console.log(res,'res');
    }
    const changePage = (page) => {
        _initData(page);
    };

    return (
        <Table
            pagination={{ defaultPageSize: 5, onChange: changePage, total }}
            columns={columnData[type]}
            dataSource={currentData}
            rowKey={columns => columns._id }
        />
           
    );
}

export default RecordTable;

src\components\Dialog\index.jsx

封装Dialog组件

import React from 'react';
import { Modal } from 'antd';
const Dialog = ({title, dialogStatus, render, setDialogStatus, width= 600}) => {
    return (
        <Modal
         width= {width}
         destroyOnHidden={true}
         title={title}
         open={dialogStatus}
         onCancel={setDialogStatus}
         footer={null}
        >
            {render()}
        </Modal>
    );
}

export default Dialog;

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor