• React 跨页面保留前一页状态的一种实现方法


    功能需求:React单页应用的时候,用户打开A页面,然后操作了A页面相关功能,比如在table里面进行了筛选,选中了几个选项。 然后点击查看详情跳转到B页面,B页面操作完的时候,点击按钮跳转到A页面,这时候A页面之前选中的几个选项往往会丢失,这时候需要怎样做才能对A页面操作的状态进行保留。

    实现思路:因为进入B页面,往往则需要点击按钮或操作某个事件,那么这里就可以对路由进行一个传参操作,带入到B页面。然后B页面接收到A页面传过来的参数,操作完B页面功能之后点击跳转返回到A页面的时候,再把之前传给B页面的参数传给A页面即可。
    首先我们要知道 React 路由跳转是可以通过dom和js的形式进行跳转,这里则采用js形式进行参数传递(这里我采用的React Hooks写法进行案例编码)。

    A页面代码片段:

    import React, { useState } from 'react';
    // 引入要用到的 hooks
    import { useHistory, useLocation } from 'react-router-dom';
    
    function aPage(){
        // 页面跳转钩子
        const history = useHistory();
        // 这个 state 为主要保留操作记录的钩子 
        const { state } = useLocation();
        // 首先一开始进入到A页面state肯定是为 {} 空对象的,那么nameFilters值则为null,一旦 nameFilters 设了值之后,那么点击跳转执行跳转方法设置了state值,那么则会得到不为空的对象。
        const [nameFilters, setNameFilters] = useState(
            (state && state.nameFilters) || null
        );
        
        //假如第一步点击了操作按钮进行了值的设置
        const firstStep=()=>{
            setNameFilters([11,22,33]);
        }
        
        // 第二步点击了详情按钮跳转到了B页面,并携带了最新的 nameFilters 给state,那么当前的 state 就包含了 nameFilters 字段和值。
        const second=()=>{
            history.push({
                    pathname: `/aPage/${id}`,
                    state: { from: '/aPage', nameFilters },
            });
        }
    }

    B页面代码片段:

    // 还是使用 useLocation 钩子,进行state的值的获取
    import { useLocation } from 'react-router-dom';
    
    function bPage(){
        const { state } = useLocation();
        //假如点击了返回按钮触发了该方法,并把state带回给A页面,A页面即可根据state
        //的值进行对A页面的设值。
        const backPage = () => {
            const { history } = props;
            history.push({
                pathname: '/aPage',
                state,
            });
        };
    }


    useLocation的state理解:其实我们就可以把state理解成为url ?号后面的参数,只是react把这些参数进行了隐式传参。

    注意项:设了state值之后,把页面刷新,其实state的值是不会丢失的,这里有点像sessionStorage,只有关闭当前页面或跳转到其它页面才会消失,所以需要注意在离开页面的时候必要的时候需要清空一下state,保持“干净”。

    钩子api地址:https://reactrouter.com/web/api/Hooks

    案例代码:这里因为是随意写的完整代码,所以还需要配置一下路由才能运行,这里这是提供完整的A页面和B页面代码,不提供其它页面的逻辑代码,路由需要自己另行配置。

    /a-page/index.js

    import React, { useEffect, useState } from 'react';
    import { Table, Button } from 'antd';
    import { useHistory, useLocation } from 'react-router-dom';
    
    function APage() {
        const history = useHistory();
        const { state } = useLocation();
    
        const [nameFilters, setNameFilters] = useState(
            (state && state.nameFilters) || null
        );
    
        const columns = [
            {
                title: 'Id',
                dataIndex: 'id',
                key: 'id',
            },
            {
                title: '名称',
                dataIndex: 'name',
                key: 'name',
                filters: [
                    { text: '监测点一', value: '监测点一' },
                    { text: '监测点二', value: '监测点二' },
                ],
                filteredValue: nameFilters,
            },
            {
                title: 'id',
                dataIndex: 'id',
                key: 'id',
                render: (item) => {
                    return (
                        <Button
                            onClick={lookDetail.bind(this, item)}
                            type="primary"
                        >
                            详情
                        </Button>
                    );
                },
            },
        ];
    
        const dataSource = [
            { id: '00_a', name: '监测点零' },
            { id: '11_b', name: '监测点一' },
            { id: '22_c', name: '监测点二' },
            { id: '33_d', name: '监测点三' },
        ];
    
        const lookDetail = (id) => {
            history.push({
                pathname: `/a-page/${id}`,
                state: { from: '/a-page', nameFilters },
            });
        };
    
        const handleTableChange = (pagination, filters, sorter) => {
            const { name } = filters;
            setNameFilters(name);
        };
    
        useEffect(() => {
            console.log(state);
        }, [state]);
    
        return (
            <>
                <Table
                    columns={columns}
                    dataSource={dataSource}
                    rowKey={(data) => {
                        return `${data.id}`;
                    }}
                    onChange={handleTableChange}
                />
            </>
        );
    }
    
    export default APage;
    View Code

    /a-page/detail/index.js

    import React from 'react';
    import { useLocation, useHistory } from 'react-router-dom';
    import { Button } from 'antd';
    
    function Detail() {
        const history = useHistory();
        const { state } = useLocation();
    
        const backPage = () => {
            // 带回给 A 页面
            history.push({
                pathname: '/a-page',
                state,
            });
        };
    
        return (
            <>
                <Button onClick={backPage}>返回</Button>
            </>
        );
    }
    
    export default Detail;
    View Code
  • 相关阅读:
    MFC——9.多线程与线程同步
    hdu 1598 find the most comfortable road(并查集+枚举)
    POJ3107Godfather[树形DP 树的重心]
    Codeforces 410C.Team[构造]
    Codeforces 715A. Plus and Square Root[数学构造]
    BZOJ1015[JSOI2008]星球大战starwar[并查集]
    洛谷U4727小L的二叉树[树转序列 LIS]
    Codeforces 500B. New Year Permutation[连通性]
    Codeforces 549D. Hear Features[贪心 英语]
    Codeforces 549C. The Game Of Parity[博弈论]
  • 原文地址:https://www.cnblogs.com/zion0707/p/13491722.html
Copyright © 2020-2023  润新知