1. 程式人生 > 實用技巧 >React 跨頁面保留前一頁狀態的一種實現方法

React 跨頁面保留前一頁狀態的一種實現方法

功能需求:React單頁應用的時候,使用者開啟A頁面,然後操作了A頁面相關功能,比如在table裡面進行了篩選,選中了幾個選項。 然後點選檢視詳情跳轉到B頁面,這時候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