首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在搜索栏中搜索后导航到搜索页,并在搜索页中重用搜索栏。

在搜索栏中搜索后导航到搜索页,并在搜索页中重用搜索栏。
EN

Stack Overflow用户
提问于 2022-07-09 17:45:00
回答 1查看 640关注 0票数 1

在我的React应用程序中,除了主要内容外,在布局级别上,我还拥有一个侧栏和一个带有配置文件部分和搜索栏的标题--所有组件都不同。

标题与每个页面路径一起使用--我希望在任何路由上进行搜索;在完成搜索(与enter一起发送)之后,我会转到"/search“路径来显示和过滤结果。

这是与搜索栏组件相关的代码片段-表单:

代码语言:javascript
复制
const SearchSection = () => {
  const [value, setValue] = useState("");

  const navigate = useNavigate();
  const location = useLocation();

  const handleSearch = (event) => {
    event.preventDefault();
    if (location.pathname !== "/search") {
      navigate("/search", { state: value });
    }
  };

  return (
    <>
      <Box
        component="form"
        onSubmit={handleSearch}
        sx={{ display: { xs: "none", md: "block" } }}
      >
        <OutlineInputStyle
          id="input-search-header"
          value={value}
          onChange={(e) => setValue(e.target.value)}
          placeholder="Search"
        />
      </Box>
    </>
  );
};

export default SearchSection;

在用户提交搜索(使用enter)之后,我导航到搜索页面并显示结果:

代码语言:javascript
复制
const Search = () => {
  const [results, setResults] = useState([]);
  const [error, setError] = useState(null);

  const location = useLocation();

  function showResults() {
    const headers = { Accept: "application/ld+json" };
    const response = fetch(
      `http://localhost:1026/ngsi-ld/v1/entities?type=Sensor&q=refRoom~=.*${location.state}`,
      {
        headers,
      }
    )
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw response;
      })
      .then((data) => {
        setResults(data);
      })
      .catch((error) => {
        console.error("Error fetching data: ", error);
        setError(error);
      });
  }

  useEffect(() => {
    showResults();
  }, []);

  return (
    <Grid container spacing={gridSpacing}>
      <Grid item xs={12}>
        <TableContainer component={Paper}>
          <Table>
            <TableHead>
              <TableRow>
                <TableCell>ID</TableCell>
                <TableCell>Type</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {results.map((result) => (
                <TableRow>
                  <TableCell>{result.id}</TableCell>
                  <TableCell>{result.type}</TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      </Grid>
    </Grid>
  );
};

export default Search;

路由/MainRoutes.js文件:

代码语言:javascript
复制
import { lazy } from 'react';

import MainLayout from 'layout/MainLayout';
import Loadable from 'ui-component/Loadable';

const DashboardHome = Loadable(lazy(() => import('views/dashboard/Home')));
const SearchPage = Loadable(lazy(() => import('views/search')));

const MainRoutes = {
    path: '/',
    element: <MainLayout />,
    children: [
        {
            path: '/',
            element: <DashboardHome />
        },
        {
            path: '/search',
            element: <SearchPage />
        }
    ]
};

export default MainRoutes;

路由/index.js文件:

代码语言:javascript
复制
import { useRoutes } from 'react-router-dom';
import MainRoutes from './MainRoutes';
import AuthenticationRoutes from './AuthenticationRoutes';

export default function ThemeRoutes() {
    return useRoutes([MainRoutes, AuthenticationRoutes], config.basename);
}

App.js文件:

代码语言:javascript
复制
import { FirebaseProvider } from 'contexts/Firebase';
import Routes from 'routes';

const App = () => {
    return (
        <FirebaseProvider>
            <>
                <Routes />
            </>
        </FirebaseProvider>
    );
};

export default App;

用户可以在任何路由上开始搜索,不管他在哪里,他都被重定向到/search。搜索栏是MainLayout组件的子组件。MainLayout组件有侧边栏、标题(其中有搜索栏)和主要内容,后者是SearchPage组件、DashboardHome等。

到目前为止,它运行良好,当我想重新使用/search路由中已经存在的搜索栏时,问题就出现了--它不会刷新页面。

我如何解决这个问题和/或什么是最好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-09 20:51:53

问题

当`"/search".

  • The路径已经在SearchPage组件上时,SearchSection不会使用新的搜索值导航到"/search",不会“侦听”路由状态(来自location对象)的更改,从而使用新的搜索参数调用showResults

解决方案

只需无条件地导航到具有新搜索状态的"/search"。或者,只在有搜索值的情况下发出导航请求。当路由状态值发生变化时,将调用useEffect钩子回调并发出提取请求。

代码语言:javascript
复制
const SearchSection = () => {
  const [value, setValue] = useState("");

  const navigate = useNavigate();

  const handleSearch = (event) => {
    event.preventDefault();
    if (value) {
      navigate("/search", { state: value, replace: true });
    }
  };

  return (
    <>
      <Box
        component="form"
        onSubmit={handleSearch}
        sx={{ display: { xs: "none", md: "block" } }}
      >
        <OutlineInputStyle
          id="input-search-header"
          value={value}
          onChange={(e) => setValue(e.target.value)}
          placeholder="Search"
        />
      </Box>
    </>
  );
};

解压缩路由状态,并将其用作useEffect钩子在SearchPage中的依赖项。

代码语言:javascript
复制
const Search = () => {
  const [results, setResults] = useState([]);
  const [error, setError] = useState(null);

  const { state } = useLocation(); // <-- unpack route state

  useEffect(() => {
    const headers = { Accept: "application/ld+json" };

     // pass in queryString
    const url = `http://localhost:1026/ngsi-ld/v1/entities?type=Sensor&q=refRoom~=.*${state || ''}`;

    fetch(url, { headers })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw response;
      })
      .then((data) => {
        setResults(data);
      })
      .catch((error) => {
        console.error("Error fetching data: ", error);
        setError(error);
      });
  }, [state]); // <-- use as effect dependency

  return (
    ...
  );
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72923507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档