我正在try 使用Reaction路由中的useSubmit钩子创建一个带有清除按钮的搜索栏.搜索查询应在输入更改和点击按钮时提交.

SearchBar.tsx

import { Form, useSubmit } from 'react-router-dom';
import { ChangeEvent, useState } from 'react';

export default function SearchBar({ query }: { query?: string }) {
  const submit = useSubmit();
  const [q, setQ] = useState(query ?? '');

  function handleChange(event: ChangeEvent<HTMLInputElement>) {
    setQ(event.target.value);
    submitForm(event.currentTarget.form);
  }

  function handleClear(event: any) {
    setQ('');
    submitForm(event.currentTarget.form);
  }

  function submitForm(submitTarget: any) {
    const isFirstSearch = q == null;
    submit(submitTarget, {
      replace: !isFirstSearch,
    });
  }

  return (
    <Form role="search">
      <input
        type="search"
        name="q"
        value={q}
        onChange={handleChange}
        autoComplete="off"
      />
      {q && q.length > 0 && (
        <button type="button" onClick={handleClear}>
          Clear
        </button>
      )}
    </Form>
  );
}

所有人.多伦多证券交易所.

import { getTodos } from '../todos';
import { useLoaderData } from 'react-router-dom';
import SearchBar from '../SearchBar';

export async function loader({ request }: { request: Request }) {
  const url = new URL(request.url);
  const q = url.searchParams.get('q');
  const todos = await getTodos(q);
  return { todos, q };
}

export default function Todos() {
  const { todos, q }: any = useLoaderData();

  return (
    <div>
      <SearchBar query={q} />
      <div>
        {todos.length > 0 ? (
          todos.map((todo: any) => <div key={todo.id}>{todo.text}</div>)
        ) : (
          <p>No todos</p>
        )}
      </div>
    </div>
  );
}

当我单击Clear按钮时,输入将被清除,但提交的查询仍具有以前的值.

StackBlitz

推荐答案

以下是我能够提出的适用于您描述的两个用例的方法.

  1. 将对submitForm的调用移动到Form组件的onChange处理程序,以便在表单数据更改时提交表单数据.
  2. input元素的onChange处理程序只更新本地q状态,而valueprops 现在被删除为uncontrolled输入.我们只需要q状态来有条件地呈现"Clear"按钮.
  3. "Clear"(清除)按钮应该转换为type="submit",然后在点击时也提交表格.
  4. handleClear处理程序应该101表单域数据.
export default function SearchBar({ query }: Props) {
  const submit = useSubmit();
  const [q, setQ] = useState(query ?? '');

  function handleChange(event: ChangeEvent<HTMLInputElement>) {
    setQ(event.target.value);
  }

  function handleClear(event: any) {
    event.currentTarget.form.reset();
  }

  function submitForm(event: any) {
    const isFirstSearch = q == null;
    submit(event.currentTarget, {
      replace: !isFirstSearch,
    });
  }

  return (
    <Form role="search" onChange={submitForm}>
      <input
        type="search"
        name="q"
        onChange={handleChange}
        autoComplete="off"
      />
      {!!q.length && (
        <button type="submit" onClick={handleClear}>
          Clear
        </button>
      )}
    </Form>
  );
}

Javascript相关问答推荐

布局样式在刷新时不持续

vanillajs-datepicker未设置输入值,日期单击时未触发更改事件

仅圆角的甜甜圈图表

materialized - activeIndex返回-1

如何从JSON数组添加Google Maps标记—或者如何为数组添加参数到标记构造器

如何使覆盖div与可水平滚动的父div相关?

配置WebAssembly/Emscripten本地生成问题

在我的html表单中的用户输入没有被传送到我的google表单中

html + java script!需要帮助来了解为什么我得到(无效的用户名或密码)

如何在JavaScript文件中使用Json文件

如何将数据块添加到d3力有向图中?

为什么这个.add.group({})在教程中运行得很好,但在我的游戏中就不行了?

如何在JAVASCRIPT中合并两组对象并返回一些键

如果没有页面重新加载Angular ,innerHTML属性绑定不会更新

用另一个带有类名的div包装元素

KeyboardEvent:检测到键具有打印的表示形式

使用Java脚本在div中创建新的span标记

为什么我的InDesign Java脚本不能完全工作?

观察子组件中的@Output事件emits 器?

Node.js的Fetch()调用总是创建新的Express会话