之前用react的做的项目一直都是用class ,setState,componentDidMount ,componentDidUpdate ,componentWillUnmount 的写法,但从16.8以来,react新增了Hook特性,对于喜欢技术尝试我的来说,岂能不试一下新写法。
我们一般用react 的ant-design框架做后台管理系统,那么最常见的业务场景就是表格,查询,分页。下面我就拿最常用的一个例子和大家分享一下:
首先请看我们的界面:
上面是搜索条件,中间是表格,下面是分页。这个大家一眼就能看懂,那么我就来给大家上代码
//注意这个js代码整个对应上面的UI展示,是我们项目里的一个页面,里面部分字段可能大家可能用不上。 import React, { useCallback, useEffect, useState} from 'react'; import {Collapse, Table, Button, Space, Form, Input, Select, DatePicker,} from 'antd'; //注意此处是我们请求接口后返回的数据,这里我是把所有的api请求都提出来了,下面filterUser和getList就是我们这个页面需要用到的api import {filterUser, getList} from "../../service/user"; //moment是为了时间选择器,选择后进行时间格式化所用 import moment from 'moment'; import 'moment/locale/zh-cn'; //locale是为了中文化时间控件的,如果其他的控件是非中文的,也可以按照这个写法中文化 import locale from 'antd/es/locale/zh_CN'; //引入本页面的样式文件 import "./list.css"; const {Panel} = Collapse; const {Option} = Select; const {RangePicker} = DatePicker; function List() { //设置页码 let [page,setPage] = useState(1); //设置每页条数 let size = 2; //设置总页数 const [total,setTotal] = useState(0); //搜索条件 let filter = { mobile:'', nickname:'', channel_id:0, tag_key:'', min_create_time:0, max_create_time:0, }; //请求数据时loading状态 const [load,setLoad] = useState(false); //表格数据 const [tableData,setTableData] = useState([]); //此处是为了初始化时候请求一次数据 useEffect(()=>{ pageChange(page,size); },[]) //点击下面的分页按钮触发的方法 const pageChange = useCallback( (currentPage,currentSize)=>{ // debugger console.log(currentPage,currentSize,"1") page = currentPage === undefined ? page : currentPage; setPage(page); size = currentSize === undefined ? size : currentSize; fetchData(); }, [] ) //点击搜索按钮触发的方法 const searchData = useCallback( (values)=>{ // debugger console.log(values) filter.mobile = values && values.mobile !== undefined ? values.mobile : ''; filter.nickname = values && values.nickname !== undefined ? values.nickname : ''; filter.channel_id = values && values.channel_id !== undefined ? values.channel_id : 0; filter.tag_key = values && values.tag_key !== undefined ? values.tag_key : ''; if(values && values.create_time !== undefined){ let min_create_time = parseInt(moment(values.create_time[0]).valueOf()/1000); let max_create_time = parseInt(moment(values.create_time[1]).valueOf()/1000); filter.min_create_time = min_create_time; filter.max_create_time = max_create_time; }else{ filter.min_create_time = 0; filter.max_create_time = 0; } page = 1; setPage(page); console.log("search",page,size) console.log("search filter",filter) fetchData(); },[] ) //Api请求后台接口的方法 const fetchData = async()=> { setLoad(true); let params = {page, size, ...filter}; let result = await getList(params); setLoad(false); if (result.code === 0) { result = result.data; console.log("result", result); let table = [...result.list]; setTotal(result.total_size); setTableData([...table]); console.log("table", table) } } //表头列 const columns = [ { title: '用户ID', dataIndex: 'id', }, { title: '昵称', dataIndex: 'nickname', }, { title: '手机号', dataIndex: 'mobile', }, { title: '来源渠道', dataIndex: 'reg_channel_desc', }, { title: '注册时间', dataIndex: 'create_time_desc', }, ]; //获取搜索条件的api const [user_channel,setUser_channel] = useState([]); const [user_tag,setUser_tag] = useState([]); useEffect(()=>{ let params = { show_user_tag:true, show_user_channel:true, show_user_identifier:true, }; const fetchData = async ()=>{ const result = await filterUser(params); if(result.code === 0){ const userChannel = result.data&&result.data.user_channel ? result.data.user_channel : []; const userTag = result.data&&result.data.user_tag ? result.data.user_tag : []; setUser_channel(userChannel); setUser_tag(userTag); } } fetchData(); },[]) //重置表单 const [form] = Form.useForm(); const reset = ()=>{ form.resetFields(); //此处尤其要注意,resetFields表单重置后会重新mount组件,因此不必在这里重新调用请求api的接口。 //重置之后,会自动调用搜索列表的方法。 } return ( <div> <h1>用户列表</h1> <Collapse defaultActiveKey={['1']} style={{marginBottom:'20px'}}> <Panel header="搜索条件" key="1"> <Form className="list" autoComplete="off" layout="inline" name="basic" form={form} initialValues={{remember: true}} onFinish={searchData} > <Form.Item label="手机号" name="mobile" > <Input allowClear/> </Form.Item> <Form.Item label="昵称" name="nickname" > <Input allowClear/> </Form.Item> <Form.Item label="用户标签" name="tag_key" > <Select showSearch allowClear style={{width: 200}} placeholder="选择用户标签" optionFilterProp="children" filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 } > { user_tag.map((item, i) => { return ( <Option value={item.key} key={item.key}>{item.val}</Option> ) }) } </Select> </Form.Item> <Form.Item label="来源渠道" name="channel_id" > <Select showSearch allowClear style={{width: 200}} placeholder="选择来源渠道" optionFilterProp="children" filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 } > { user_channel.map((item, i) => { return ( <Option value={item.key} key={item.key}>{item.val}</Option> ) }) } </Select> </Form.Item> <Form.Item label="注册时间" name="create_time" > <RangePicker locale={locale}/> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit"> 查询 </Button> <Button htmlType="submit" className="reset" onClick={reset}> 重置 </Button> </Form.Item> </Form> </Panel> </Collapse> <Table rowKey="id" columns={columns} loading={load} dataSource={tableData} bordered scroll={{y: 500}} rowSelection={{selectedRowKeys: []}} pagination={{showSizeChanger:true,onChange:pageChange, pageSizeOptions:['2','5','10'],defaultPageSize:size, showTotal: ()=>{return `共${total}条数据`}, current:page,total:total}} /> </div> ); } export default List;既然大家使用hook写东西了,那么关于hook的一些知识肯定也有一些了解,很多文章和博客也有介绍,这里我就不多说了,下面为大家附上官网地址:react hook官网地址
这是我在项目里能想到的一个写法,如果大家有更好的写法,欢迎和我分享。非常乐意和大家一起学习,一起进步。