React - 查询参数在页面加载时为空

React - Query Parameters Are Empty on Page Load

我在 React 中遇到导航逻辑问题,如果能得到一些帮助会很棒。

我有使用 TypeScript、React 和 Ionic Framework V5 编写的前端 Web 应用程序。

该应用程序有一个相当标准的搜索框,可重定向到位置为 /search?query={query here} 的结果页面。

当我点击搜索按钮时,导航由 React Router 处理。我被重定向到结果页面,搜索查询出现在浏览器的地址栏中,但在功能组件逻辑中提取时查询字符串为空 - 给我不正确的搜索结果。

搜索框路由到结果页面,如下所示:

<IonButton fill="clear" className="search-button" routerLink={`/search?query=${searchValue}`}>
  <IonIcon name="search-outline" />
</IonButton>

在搜索页面上,查询字符串是这样读的:

const Home: React.FC<SimplePageProps> = ({ axios }) => {
  const queryParams = useQuery();
  const param = queryParams.get('query');

  const [products, setProducts] = useState([]);

  useEffect(() => {
    axios.get(`/products?query=${param}`)
      .then((response) => {
        const data = camelcaseKeys(response.data, { deep: true });
        setProducts(data.items.map((product: Product) => (
          <IonCol key={product.id} size-md="4" size-xl="3">
            <ProductCard product={product} />
          </IonCol>
        )));
      })
      .catch((error) => {
        // TODO show error element
        console.error(error);
      });
  }, [axios, param]);

如前所述,当在功能组件逻辑中获取查询字符串时,查询字符串为空 - 给我的搜索结果不正确。当我刷新页面时,查询字符串不为空并显示搜索结果。有什么想法吗?

提前致谢!

在沉睡并进行更多搜索后,我设法解决了这个问题。

我的解决方案是将内容剥离回原始 JavaScript 命令,window.location.search。这总是从 URL 获取正确的查询参数,而 React Router 辅助挂钩在首次路由到页面时将是 undefined

useLocation() 包含在内,以便在从结果页面执行另一次搜索时,React 组件 re-renders 反映新的查询字符串。

const Home: React.FC<SimplePageProps> = ({ axios }) => {
  // parse query string parameter
  const { search } = window.location;
  const query = new URLSearchParams(search).get('query');

  useLocation(); // including this forces a re-render when the URL changes

  const [products, setProducts] = useState([]);

  useEffect(() => {
    axios.get(`/products?query=${query}`)
      .then((response) => {
        const data = camelcaseKeys(response.data, { deep: true });
        setProducts(data.items.map((product: Product) => (
          <IonCol key={product.id} size-md="4" size-xl="3">
            <ProductCard product={product} />
          </IonCol>
        )));
      })
      .catch((error) => {
        // TODO show error element
        console.error(error);
      });
  }, [axios, query]);