react组件返回上级时,记录上级组件状态

    技术2022-07-11  124

    最近开发项目中,做管理后台,很多表格列表,有搜索条件,有分页;在跳转到详情页面,返回时,列表组件重新渲染,之前的搜索条件,分页什么的,都没有记住;还需要重新选,点击,交互体验很不好。

    1.这里想到2两个办法,一个是吧搜索条件存到缓存中;每次进行读写;条件太多,或者多个上级页面跳转到同一页面,再返回是还得区分,很是麻烦。而且点击浏览器的返回按钮,没办法记录

    这里我们用路由传递,参数的办法;上级页面把搜索条件传给,下级页面;下级页面返回时,在传给上级页面

    主要看,state和history传值就行了

    上级页面代码:

    /* * 代理任务 */ import React, { Component } from "react"; import Storage from "store2"; import History from "@utils/history"; import { Table, Select, Button, DatePicker, Modal, Notification, Row, Col } from "antd"; import moment from "moment"; import Request from "@utils/request"; import { urlAppendQuery } from "@utils/tools"; import { number4 } from "@utils/changeMoneyUnit"; import { bankShortName } from "@utils/codeToName"; import ModalDetail from "./form.js"; import "./style.less"; const curBranchCode = Storage.get("loginRes").bank.code; const agentType = Storage.get("loginRes").bank["agentType"]; const chost = Storage.get("chost"); // 格式化时间 const format = "YYYY-MM-DD"; const taskStatus = { "1": "未出库", "2": "在途", "3": "已完成", }; // 显示弹框标题 const showTitle = (modalType) => { let zz = ""; if (modalType === "add") { zz = "新建任务"; } else if (modalType === "edit") { zz = "修改任务"; } return zz; } const columns = (_this) => [ { title: "任务编号", dataIndex: "taskCode", width: 200, align: "center", }, { title: "出库银行", dataIndex: "outBank", width: 150, align: "center", render: (text) => <span>{bankShortName(text) || "--"}</span> }, { title: "入库银行", dataIndex: "inBank", width: 150, align: "center", render: (text) => <span>{bankShortName(text) || "--"}</span> }, { title: "任务金额(元)", dataIndex: "amount", width: 100, align: "center", render: (text) => number4(text) }, { title: "双流(元)", dataIndex: "doubleAmount", width: 100, align: "center", render: (text) => number4(text) }, { title: "非双流(元)", dataIndex: "freeAmount", width: 100, align: "center", render: (text) => number4(text) }, { title: "任务时间", dataIndex: "taskTime", align: "center", width: 100, render: (text) => <div>{text ? moment(text).format(format) : "--"}</div> }, { title: "业务类型", dataIndex: "taskType", align: "center", width: 100, render: (text) => taskType[text] }, { title: "业务状态", dataIndex: "taskStatus", align: "center", width: 100, render: (text) => taskStatus[text] }, { title: "创建人", dataIndex: "createOperator", align: "center", width: 150, render: (text) => <span>{text || "--"}</span> }, { title: "创建时间", dataIndex: "createTime", align: "center", width: 100, render: (text) => <div>{text ? moment(text).format(format) : "--"}</div> }, { title: "操作", dataIndex: "操作", fixed: "right", align: "center", width: 240, render: (text, record) => ( <div style={{ textAlign: "center" }}> { record.taskStatus === 1 && <Button type="link" size="small" onClick={() => { let aa = ""; if ((curBranchCode === record.inBank) && agentType === 1) { aa = "pay"; } else if ((curBranchCode === record.outBank) && agentType === 2) { aa = "pay"; } else { aa = "get"; } _this.toggleModal(record, "edit", aa); // get被代理行入库,pay被代理行出库 }} > 修改 </Button> } { record.taskStatus === 2 && curBranchCode === record.inBank && <Button type="link" size="small" onClick={() => { History.push("/transferInRoom", { taskCode: record.taskCode, type: "agent", }); }} > 入库 </Button> } { record.taskStatus === 1 && curBranchCode === record.outBank && <Button type="link" size="small" onClick={() => { History.push("/transferOutRoom", { taskCode: record.taskCode, type: "agent", }); }} > 出库 </Button> } <Button type="link" size="small" onClick={() => { History.push("/transferTaskDetail", { taskCode: record.taskCode, fromUrl: "/agent", time: [_this.state.startTime, _this.state.endTime].join(","), taskStatus: _this.state.taskStatus, nowPage: _this.state.nowPage, }); }} > 任务详情 </Button> { record.taskStatus === 1 && <Button type="link" roles="button" style={{ color: "#ff0000" }} onClick={() => { Modal.confirm({ title: "确定删除代理任务?", content: ( <div> <p>任务号:{record.taskCode},</p> <p>任务金额:{record.amount}</p> </div> ), okText: "确认", cancelText: "取消", onOk() { Request.POST(`/api/api/task/delete/${record.taskCode}`).then((res) => { if (res.success) { Notification.success({ message: res.message || "删除成功" }); _this.loadData({ page: 1 }); // 回到第一页 } else { Notification.error({ message: res.message || "删除失败" }); } }); } }); }} > 删除 </Button> } </div> ) } ]; class View extends Component { constructor(props) { super(props); const isHaveSearch = Boolean(this.props.location.state); this.state = { startTime: isHaveSearch ? moment(this.props.location.state.time.split(",")[0]) : moment(), endTime: isHaveSearch ? moment(this.props.location.state.time.split(",")[1]) : moment(), tableSource: {}, // 表格数据 modalShowed: false, // 调入调出弹出框 modalType: "add", // 弹窗默认类型新增add,修改edit modalCode: "", // 弹窗任务编码 modalId: "", // 弹窗任务ID moneyType: "", // 被代理行出入库类型 taskTypeArr: [2], // 任务类型任务类型1:跨行调款 2:代理任务 3:向人行交款 4:从人行取款 5:上缴残损券 taskStatus: isHaveSearch ? this.props.location.state.taskStatus : null, // 任务状态 endOpen: false, // 时间框关闭 nowPage: isHaveSearch ? this.props.location.state.nowPage : 1, // 当前分页 }; } componentDidMount() { this.loadData(); // 获取当天数据 } disabledStartDate = startValue => { const { endTime } = this.state; if (!startValue || !endTime) { return false; } return startValue.valueOf() > endTime.valueOf(); }; disabledEndDate = endValue => { const { startTime } = this.state; if (!endValue || !startTime) { return false; } return endValue.valueOf() <= startTime.valueOf(); }; // 修改开始时间 changeStartTime = (time) => { this.setState({ startTime: time }); }; // 修改结束时间 changeEndTime = (time) => { this.setState({ endTime: time }); }; handleStartOpenChange = open => { if (!open) { this.setState({ endOpen: true }); } }; handleEndOpenChange = open => { this.setState({ endOpen: open }); }; // 渲染页面数据 loadData = async (obj) => { const { startTime, endTime, taskTypeArr, taskStatus, nowPage, } = this.state; // 获取任务列表 Request.GET("/api/api/task/pageList", { params: { pageNo: (obj && obj.page) || nowPage, pageSize: (obj && obj.limit) || 10, taskTimeBegin: moment(startTime).format(format), taskTimeEnd: moment(endTime).format(format), taskTypeList: taskTypeArr, taskStatus, } }).then((res) => { const tableData = res.data; if (res.success) { this.setState({ tableSource: tableData, nowPage: tableData.pageNo }); } else { Notification.error({ message: res.message || "后端接口数据错误" }); } }); }; taskExport = ()=>{ const { startTime, endTime, taskTypeArr, taskStatus, } = this.state; if (endTime.diff(startTime, "day") >= 366) { Notification.warn({ message: "仅支持导出最近一年内的任务!" }); } else { const downUrl = urlAppendQuery(`${chost}/cbank/api/task/export`,{ "Access-Token":Storage.get("Authorization"), taskStatus, taskTimeBegin:startTime.format(format), taskTimeEnd:endTime.format(format), taskTypeList:taskTypeArr }); // 导出任务 window.location.href = downUrl; } } // 修改、添加 toggleModal = (record, type, moneyType) => { this.setState({ modalShowed: !this.state.modalShowed, modalType: type, modalcode: type === "add" ? "" : record.taskCode, modalId: type === "add" ? "" : record.id, moneyType: moneyType }, () => { console.log(this.state.modalcode, this.state.modalType); }); }; // 点击阴影显示 handleCancel = () => { this.setState({ modalShowed: !this.state.modalShowed, }); }; CancelTaskModal = () => { this.setState({ modalShowed: !this.state.modalShowed, }); }; render() { const { startTime, endTime, taskStatus, endOpen, tableSource, modalShowed, modalType, moneyType, } = this.state; return ( <div className="list"> <Row> <Col span={14}> <Row style={{ "marginBottom": "20px" }}> <Col style={{ "marginBottom": "20px" }}> 任务时间: <DatePicker allowClear={!1} disabledDate={this.disabledStartDate} format="YYYY-MM-DD" value={startTime} placeholder="开始" onChange={this.changeStartTime} onOpenChange={this.handleStartOpenChange} /> <span className="mlr5">--</span> <DatePicker allowClear={!1} disabledDate={this.disabledEndDate} format="YYYY-MM-DD" value={endTime} placeholder="结束" onChange={this.changeEndTime} open={endOpen} onOpenChange={this.handleEndOpenChange} /> </Col> <Col> 任务状态: <Select style={{ width: "100px", marginRight: "25px" }} value={taskStatus} onChange={(val) => { this.setState({ taskStatus: val }); }} > <Select.Option value={null}>全部</Select.Option> <Select.Option value={1}>未出库</Select.Option> <Select.Option value={2}>在途</Select.Option> <Select.Option value={3}>已完成</Select.Option> </Select> <Button type="primary" onClick={() => { this.loadData({page: 1}); }} > 查询 </Button> <Button type="primary" style={{"marginLeft":"20px"}} onClick={() => { this.taskExport(); }} > 任务导出 </Button> </Col> </Row> </Col> <Col span={10}> { agentType === 1 && <Button style={{ margin: "10px", width: "150px", height: "60px" }} type="primary" onClick={() => { this.toggleModal(null, "add", "get"); // get被代理行入库,pay被代理行出库 }} > 向被代理行调款 </Button> } { agentType === 2 && <div> <Button style={{ margin: "10px", width: "150px", height: "60px" }} type="primary" onClick={() => { this.toggleModal(null, "add", "get"); // get被代理行入库,pay被代理行出库 }} > 从代理行取款 </Button> <Button type="primary" style={{ margin: "10px", width: "150px", height: "60px" }} onClick={() => { this.toggleModal(null, "add", "pay"); // get被代理行入库,pay被代理行出库 }} > 向代理行交款 </Button> </div> } </Col> </Row> <Table scroll={{ x: 1950 }} dataSource={tableSource && tableSource.dataList} columns={columns(this)} rowSelection={null} rowKey="id" pagination={{ showQuickJumper: false, total: tableSource.totalSize, current: tableSource.pageNo, pageSize: tableSource.pageSize, onChange: (page) => { this.loadData({ limit: tableSource.size, page }); }, }} /> <Modal visible={modalShowed} footer={null} destroyOnClose={!!1} onCancel={() => this.handleCancel()} width="800px" maskClosable={!1} title={showTitle(modalType)} > <ModalDetail parentThis={this} modalType={modalType} moneyType={moneyType} modalCode={this.state.modalcode} modalId={this.state.modalId} /> </Modal> </div> ); } } export default View;

    下级页面代码:

    /* * 创建代理任务 */ import React from "react"; import { Form, Notification, Button, Select, DatePicker, Row, Col, Input } from "antd"; import Request from "@utils/request"; import Storage from "store2"; import np from "number-precision"; import moment from "moment"; import { bankName } from "@utils/codeToName.js" import ValutaForm from "./valutaForm.js"; const FormItem = Form.Item; const moneyReg = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/; // 包含小数点 const dateFormat = "YYYY-MM-DD H:mm:ss"; const agentType = Storage.get("loginRes").bank["agentType"]; const currentBankCode = Storage.get("loginRes").bank.code; const currentBankName = Storage.get("loginRes").bank.name; class ViewForm extends React.Component { constructor(props) { super(props); console.log(props) this.state = { valutaList: [], // 币值表 inBank: "", outBank: "", taskTime: null, note: "", // 备注 id: "", taskCode: "", agentBankCode: "", agentBankName: "", toAgentArr: [], sureBtn: false, // 创建任务按钮 }; } componentDidMount() { if (agentType === 1) { this.getAgentArr(); // 查询代理点 if (this.props.moneyType === "get") { this.setState({ inBank: "", outBank: currentBankCode, agentBankCode: currentBankCode, agentBankName: currentBankName, }); } else if (this.props.moneyType === "pay") { this.setState({ inBank: currentBankCode, outBank: "", agentBankCode: currentBankCode, agentBankName: currentBankName, }); } } else if (agentType === 2) { // 被代理行获取代理行的编码 let agentBankCode = Storage.get("loginRes").bank["agentCode"]; let zzArr = [{ "id": 1, "code": currentBankCode, "name": currentBankName }]; if (this.props.moneyType === "get") { this.setState({ inBank: currentBankCode, outBank: agentBankCode, agentBankCode: agentBankCode, agentBankName: bankName(agentBankCode), toAgentArr: zzArr, }); } else if (this.props.moneyType === "pay") { this.setState({ inBank: agentBankCode, outBank: currentBankCode, agentBankCode: agentBankCode, agentBankName: bankName(agentBankCode), toAgentArr: zzArr, }); } } if (this.props.modalType === "edit") { this.getTaskInfo(); } else { this.getPbankValuta(); // 获取币值表 } } // 获取任务信息 getTaskInfo = () => { console.log(this.props.modalCode); Request.GET(`/api/api/task/get/${this.props.modalCode}`).then((res) => { if (res.success) { this.setState({ valutaList: res.data.taskValutaList, inBank: res.data.task.inBank, note: res.data.task.note, outBank: res.data.task.outBank, taskTime: moment(res.data.task.taskTime), id: res.data.task.id, taskCode: res.data.task.taskCode, }); } else { Notification.warning({ message: res.message || "获取该任务的调款信息失败", }); } }); } // 获取被代理银行列表 getAgentArr = () => { Request.GET(`/api/api/bank/agent?agentBankCode=${currentBankCode}`).then((res) => { if (res.success) { this.setState({ toAgentArr: res.data, }); } else { Notification.warning({ message: res.message || "获取被代理银行信息失败", }); } }); }; // 获取币值表 getPbankValuta = () => { Request.GET("/api/api/valuta/list").then((res) => { if (res.success) { this.setState({ valutaList: res.data.map(item => { item.valutaAmount = 0; return item; }), // inBank: "", // outBank: "", // taskTime: null, // id: "", // taskCode: "", }); } else { Notification.warning({ message: res.message || "获取币值列表失败", }); } }); }; disabledDate = (current) => { // Can not select days before today and today return current && current < moment().endOf("day"); } changePbankValutaList = (value, record) => { if (!value || moneyReg.test(value)) { this.setState({ valutaList: this.state.valutaList.map(item => { if (item.code === record.code) { item.valutaAmount = value; } return item; }) }) } else { Notification.warning({ message: "请输入合法数值!", }); } } compute = () => this.state.valutaList.reduce((total, item) => np.plus(total, item.valutaAmount), 0); slCompute = () => { return this.state.valutaList.reduce((total, item) => { if (item.flag === 1) { return np.plus(total, item.valutaAmount); } return total; }, 0); }; fslCompute = () => { return this.state.valutaList.reduce((total, item) => { if (item.flag === 0) { return np.plus(total, item.valutaAmount); } return total; }, 0); }; handleSubmit = () => { if (this.compute() === 0 || this.compute() < 0) { Notification.warning({ message: "调款金额不能小于等于0元!", }); this.setState({ sureBtn: false }); return; } const { id, taskCode } = this.state; const { form: { validateFields }, modalType } = this.props; validateFields((err, values) => { if (!err) { if (modalType === "edit") { Request.POST("/api/api/task/update", { body: { task: { id, taskCode, inBank: values.inBank, inBankName: bankName(values.inBank), outBank: values.outBank, outBankName: bankName(values.outBank), taskTime: values.taskTime.format(dateFormat), taskType: 2, remark: values.remark }, taskValutaList: values.taskValutaList.valuta.filter(item => item.valutaAmount > 0).map(item => { let temp = {}; temp.valutaCode = item.code; temp.valutaFlag = item.flag; temp.valutaAmount = item.valutaAmount; return temp; }) } }).then((res) => { if (res.success) { Notification.success({ message: res.message || "修改调款任务成功", }); this.props.parentThis.CancelTaskModal(); this.props.parentThis.loadData(); } else { Notification.warning({ message: res.message || "修改调款任务成功失败", }); } this.setState({ sureBtn: false }); }); } else { Request.POST("/api/api/task/add", { params: { loginKey: "b02a523f8ec348feb30aac2ea794724c", }, body: { task: { inBank: values.inBank, inBankName: bankName(values.inBank), outBank: values.outBank, outBankName: bankName(values.outBank), taskTime: values.taskTime.format(dateFormat), taskType: 2, //1:跨行调款 2:代理任务 3:向人行交款 4:从人行取款 5:上缴残损券 remark: values.remark }, taskValutaList: values.taskValutaList.valuta.filter(item => item.valutaAmount > 0).map(item => { let temp = {}; temp.valutaCode = item.code; temp.valutaFlag = item.flag; temp.valutaAmount = item.valutaAmount; return temp; }) } }).then((res) => { if (res.success) { Notification.success({ message: res.message || "创建调款任务成功", }); this.props.parentThis.CancelTaskModal(); this.props.parentThis.loadData(); } else { Notification.warning({ message: res.message || "创建调款任务成功失败", }); } this.setState({ sureBtn: false }); }); } } }); }; render() { const { getFieldDecorator, getFieldValue } = this.props.form; const { sureBtn, toAgentArr, agentBankCode, agentBankName, valutaList, inBank, outBank, taskTime, remark } = this.state; const { modalType, moneyType } = this.props; console.log(toAgentArr); const formItemLayout = { labelCol: { span: 3 }, wrapperCol: { span: 16 }, }; const formItemLayoutValuta = { labelCol: { span: 3 }, wrapperCol: { span: 20 }, } const _this = this; return ( <Row className="modalForm"> <Col> <Form> <FormItem label="时间" {...formItemLayout}> {getFieldDecorator("taskTime", { initialValue: taskTime, rules: [{ required: true, message: "请输入调款时间!" }], })( <DatePicker allowClear={!1} disabledDate={this.disabledDate} showTime={{ format: "HH:mm" }} format="YYYY-MM-DD HH:mm" placeholder="请选择调款任务时间" /> )} </FormItem> <FormItem label="出库行" {...formItemLayout}> {getFieldDecorator("outBank", { initialValue: outBank, rules: [{ required: true, message: "请输入调款出库行!" }, { validator: (rule, value, callback) => { if (getFieldValue("inBank") === value) { callback("出库行和入库行不能为同一银行!"); } callback(); } }], })( <Select showSearch placeholder="请选择出库行" disabled={agentType === 2 || modalType === "edit"} optionFilterProp="children" filterOption={(input, option) => option.props.children.indexOf(input) >= 0 } > { moneyType === "get" ? <Select.Option value={agentBankCode} > {agentBankName} </Select.Option> : toAgentArr.map(item => { return <Select.Option value={item.code} key={item.id} > {item.name} </Select.Option> }) } </Select> )} </FormItem> <FormItem label="入库行" {...formItemLayout}> {getFieldDecorator("inBank", { initialValue: inBank, rules: [ { required: true, message: "请输入调款入库行!" }, { validator: (rule, value, callback) => { if (getFieldValue("outBank") === value) { callback("出库行和入库行不能为同一银行!"); } callback(); } }], })( <Select showSearch disabled={agentType === 2 || modalType === "edit"} placeholder="请选择入库行" optionFilterProp="children" filterOption={(input, option) => option.props.children.indexOf(input) >= 0 } > { moneyType === "pay" ? <Select.Option value={agentBankCode} > {agentBankName} </Select.Option> : toAgentArr.map(item => { return <Select.Option value={item.code} key={item.id} > {item.name} </Select.Option> }) } </Select> )} </FormItem> <FormItem label="币值" {...formItemLayoutValuta}> {getFieldDecorator("taskValutaList", { initialValue: { valuta: valutaList } })( <ValutaForm getFieldDecorator={getFieldDecorator} changePbankValutaList={this.changePbankValutaList} parentThis={this} /> )} </FormItem> <FormItem label="备注说明" {...formItemLayout}> {getFieldDecorator("remark", { initialValue: remark, rules: [{ required: false, message: "请填写备注说明", }], })( <Input.TextArea placeholder="请填写备注说明" /> )} </FormItem> </Form> </Col> <Col style={{ "textAlign": "right" }}> <Button type="primary" htmlType="submit" disabled={sureBtn} onClick={() => { this.setState({ sureBtn: true, }, ()=> { // 解决一下setState异步问题 setTimeout(() => { _this.handleSubmit(); }, 500); }); }}>确定</Button> <Button style={{ "marginLeft": 8 }} onClick={() => { this.props.parentThis.CancelTaskModal(); }}>取消</Button> </Col> </Row> ); } } const View = Form.create()(ViewForm); export default View;

     

    Processed: 0.012, SQL: 9