reactjs 使用NextJS中的输入更新页面的查询参数(应用程序路由器)

9fkzdhlc  于 5个月前  发布在  React
关注(0)|答案(3)|浏览(88)

我尝试使用onChange事件根据用户输入动态更新查询参数。然而,我遇到了一个问题,在输入文本时,查询参数首先更新,只有在短暂的延迟之后,输入值才会更新。我的目标是实现输入值和查询参数之间的实时同步,但当前的实现无法实现这一点。
下面是在Next.js 14环境(App Router)中实现的相关JavaScript代码,使用了useSearchParams、usePathname和useRouter钩子。我已经将“use client”放在了组件的顶部。

const searchParams = useSearchParams();
const pathname = usePathname();
const router = useRouter();

const name = searchParams.get('name') || '';

const handleFilter = (e) => {
    const { name: key, value } = e.target;

    const params = new URLSearchParams(searchParams);

    params.set(key, value);
    params.set('page', 1);

    router.push(`${pathname}?${params.toString()}`);
};

<input
    type="text"
    className="form-control"
    placeholder="Name of the user"
    id="name"
    name="name"
    value={name}
    onChange={handleFilter}
/>

字符串
一个解决方案是使用浅路由,但我找不到任何使用浅等于真的useRouter(来自next/navigation)的文档。

4dbbbstv

4dbbbstv1#

你可以看看这个

import { usePathname, useSearchParams, useRouter } from "next/navigation";
import { useState, useEffect } from "react";

export default function Home() {
  const [searchQuery, setSearchQuery] = useState({
    name: "",
    // you can add more keys to this
  });
  const searchParams = useSearchParams();
  const pathname = usePathname();
  const router = useRouter();

  const handleInputChange = (event) => {
    const { name, value } = event.target;
    const updatedQuery = { ...searchQuery, [name]: value };
    setSearchQuery(updatedQuery);
    updateSearchQuery(updatedQuery);
  };

  const updateSearchQuery = (updatedQuery) => {
    const params = new URLSearchParams(searchParams);
    Object.keys(updatedQuery).forEach((key) => {
      if (updatedQuery[key]) {
        params.set(key, updatedQuery[key]);
      } else {
        params.delete(key);
      }
    });
    params.set('page', '1');
    const queryString = params.toString();
    const updatedPath = queryString ? `${pathname}?${queryString}` : pathname;
    router.push(updatedPath);
  };

  return (
    <main>
      <div>
        <input
          type="text"
          className="form-control"
          placeholder="Name of the user"
          id="name"
          name="name"
          value={searchQuery.name}
          onChange={handleInputChange}
        />
      </div>
    </main>
  );
}

字符串

smtd7mpg

smtd7mpg2#

通过保持值处于一种状态来控制输入将使其保持无功。
更详细地说:
1.使用search参数保持状态。
1.添加按下(或更改)监听器以更新状态。
1.更新useEffect中的搜索参数。

const [search, setSearch] = useState(value);
const searchParams = useSearchParams();
const pathname = usePathname();
const router = useRouter();

useEffect(() => {
    const params = new URLSearchParams(searchParams);
    params.set('name', search);
    params.set('page', 1);
    router.push(`${pathname}?${params.toString()}`);    
}, [search]

const changeHandler = (e) => {
    const { value } = e.target;
    setSearch(value);
}

<input
    type="text"
    className="form-control"
    placeholder="Name of the user"
    id="name"
    name="name"
    value={search}
    onkeydown={changeHandler }
/>

字符串

unguejic

unguejic3#

我现在使用的是history.replaceState()
在Safari和iOS上有一个小问题,在10秒内调用这个命令上千次会导致客户端错误。我的应用程序涉及一个颜色选择器,它将颜色存储在状态中,在颜色选择器周围拖动一段时间会导致这个问题。
除此之外,它对我来说非常好用。对于你的使用,这个应该恰到好处。
下面是一个完全工作的客户端组件和你的代码(Next 14 App Router)。

"use client";

import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";

const Page = () => {
    // removed useRouter because it was unused and doesnt support shallow routing in App Router
    const searchParams = useSearchParams();
    const params = new URLSearchParams(searchParams);
    const pathname = usePathname();

    // Store name and url state in a variable
    const [name, setName] = useState<string>("");
    const [urlState, setUrlState] = useState<string>("");

    // params helper function
    const setParams = (key: string, value: string | number) => {
        params.set(key, value.toString());
    };

    // useEffect to set the name and page params on pageload and when the name from the imnput changes
    useEffect(() => {
        console.log(name);
        setParams("name", name);
        setParams("page", 1);
        history.replaceState(null, "", `${pathname}?${params.toString()}`);
    }, [name]);

    // modified handlefilter function to set the name state
    const handleFilter = (e: any) => {
        const { name: key, value } = e.target;
        setName(value);
    };

    // component
    return (
        <input
            type="text"
            className="form-control"
            placeholder="Name of the user"
            id="name"
            name="name"
            value={name}
            onChange={handleFilter}
        />
    );
};

export default Page;

字符串
希望这对你有用!我希望他们能为应用路由器实现一个浅路由替代方案。在那之前,我会用我的生活方式穴居人。

相关问题