后台管理路由跳转回来怎么保留搜索表单参数?

后台管理大致有两种页面
一种是带搜索表单和表格的数据展示页面 在下面称A页面
一种是表单的数据新增/编辑页 在下面称B页面

现在需要在A跳到B的时候 记录表单的搜索状态 等B回到A的时候 把状态重新赋值给表单

想问下大佬们有没有好的方法
我目前只能想到一个方法
1:从A去B的时候把搜索表单的参数拼接到地址栏 然后点返回A的时候 把参数再带回A 然后去重新赋值 但是感觉可维护性和可阅读性都很差,而且需要一个页面一个页面的做处理,需要A跳B的页面也很多

另外觉得监听路由变化做处理是最简单也是最好维护的 但是具体咋做还在想 想法还没有打通

补充:有第二种想法是因为维护过一个后台管理项目 做法比较'新颖'(我第一次见) 表单表格字段以及值(例如obj:{name:1},obj、name、1 三个都是后端在数据库维护的) 每个页面调一个接口 传当前页面的pathname 然后后端返回一堆配置 然后前端页面都是组件化 所以它那个项目监听路由变化很简单 因为所有的页面 都是用的一个公共大组件

阅读 1k
avatarAI BotBETA

确实,将搜索参数附加到URL中并在返回时读取它们是一种常见的方法,但它可能不是最优雅或最可维护的解决方案。此外,当参数变得复杂或数量增加时,URL可能会变得冗长且难以管理。

监听路由变化是一个更好的想法,因为这种方法更灵活且可维护。在前端,你可以使用React Router(或其他你正在使用的路由库)来监听路由变化,并在必要时恢复搜索表单的状态。

以下是一个使用React Router的基本示例,说明如何在后台管理系统中实现此功能:

  1. 安装React Router(如果你还没有安装的话):
npm install react-router-dom
  1. 在你的应用中设置路由:
import { BrowserRouter as Router, Route, Switch, useLocation, useHistory } from 'react-router-dom';

// 你的组件
import PageA from './PageA';
import PageB from './PageB';

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/a" component={PageA} />
        <Route path="/b" component={PageB} />
      </Switch>
    </Router>
  );
}

export default App;
  1. 在PageA中保存和恢复搜索表单的状态:
import React, { useState, useEffect } from 'react';
import { useLocation, useHistory } from 'react-router-dom';

function PageA() {
  const [searchParams, setSearchParams] = useState({});
  const location = useLocation();
  const history = useHistory();

  // 从URL解析搜索参数
  useEffect(() => {
    const queryParams = new URLSearchParams(location.search);
    setSearchParams(Object.fromEntries(queryParams.entries()));
  }, [location]);

  // 在跳转到其他页面时保存搜索参数
  const handleGoToPageB = () => {
    const searchParamsString = new URLSearchParams(searchParams).toString();
    history.push(`/b?${searchParamsString}`);
  };

  // 在返回PageA时恢复搜索参数
  useEffect(() => {
    if (location.pathname === '/a') {
      const queryParams = new URLSearchParams(location.search);
      setSearchParams(Object.fromEntries(queryParams.entries()));
    }
  }, [location]);

  return (
    <div>
      <h1>Page A</h1>
      <form>
        {/* 渲染搜索表单 */}
      </form>
      <button onClick={handleGoToPageB}>Go to Page B</button>
    </div>
  );
}

export default PageA;
  1. 在PageB中处理返回操作:
import React from 'react';
import { useHistory } from 'react-router-dom';

function PageB() {
  const history = useHistory();

  const handleGoBack = () => {
    history.goBack();
  };

  return (
    <div>
      <h1>Page B</h1>
      <button onClick={handleGoBack}>Go Back</button>
    </div>
  );
}

export default PageB;

在这个示例中,PageA组件使用useLocationuseEffect来监听URL的变化,并在需要时恢复搜索表单的状态。当从PageA跳转到PageB时,搜索参数会被附加到URL中。当用户从PageB返回PageA时,这些参数会被读取并用于恢复表单状态。

这种方法的好处是它是声明式的,不需要在每个页面上进行繁琐的处理。此外,它也更易于维护和扩展,因为你可以轻松地添加更多的路由和页面,而无需更改现有的逻辑。

2 个回答

这种来回跳的参数,url参数、storage、弹层都可以,封装一个工具统一来处理,都差不多。

你说的第二种,应该是属于表单保存功能,就是填到一半,点击保存,下次回来可以继续填,这种用接口来做。

下面是路由方案:
利用PersistState这个高阶组件,让列表页的状态持久化。

列表和详情页(路由方案)

import React, { useState, useEffect } from 'react';
import { RouterProvider, createHashRouter } from 'react-router-dom';

function Detail() {
  const onNavigate = () => {
    router.navigate('/');
  };

  return (
    <div>
      <h1>Detail</h1>
      <button onClick={onNavigate}>go to list</button>
    </div>
  );
}

const PersistState = (WrappedComponent) => (props) => {
  const initialState = JSON.parse(localStorage.getItem('persistState'));
  const [state, setState] = useState(initialState);

  useEffect(() => {
    localStorage.setItem('persistState', JSON.stringify(state));
  }, [state]);

  return <WrappedComponent state={state} setState={setState} {...props} />;
};

function List({ state, setState }) {
  const onNavigate = (id) => {
    router.navigate(`/detail/${id}`);
  };

  return (
    <div>
      <h1>List</h1>
      <input
        value={state.name}
        onChange={(e) =>
          setState((_state) => ({
            ..._state,
            name: e.target.value,
          }))
        }
      />
      <ul>
        <li onClick={() => onNavigate('1')}>数据1</li>
        <li onClick={() => onNavigate('2')}>数据2</li>
        <li onClick={() => onNavigate('3')}>数据3</li>
      </ul>
    </div>
  );
}

const PersistStateList = PersistState(List);

const router = createHashRouter([
  {
    path: '/',
    element: <PersistStateList />,
  },
  {
    path: '/detail/:id',
    element: <Detail />,
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

export default App;

手动持久化

const PersistState = (WrappedComponent) => (props) => {
  const initialState = JSON.parse(localStorage.getItem('persistState'));
  const [state, setState] = useState(initialState);

  const save = () => {
    localStorage.setItem('persistState', JSON.stringify(state));
  };

  const clean = () => {
    localStorage.remove('persistState');
  };

  return (
    <WrappedComponent
      state={state}
      setState={setState}
      save={save}
      clean={clean}
      {...props}
    />
  );
};

核心需求是暂存数据,问题是存在哪:
1.存store,页面刷新就没了
2.存storage,注意清除
3.缓存页面,即vue中的KeepAlivereact需要找三方库
4.存数据库,除非产品需求真的需要草稿入库才会做

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题