功能需求: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;
/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;
