URL 搜索参数被替换 - Remix 运行
URL search parameters gets replaced - Remix Run
我正在搜索 UI,其中有很多过滤器,当有人 selects/checks 选项时,我希望将其作为 URL 参数。我已经使用 Remix.run 文档中建议的技术在过滤器中提出多种形式。每次提交一组过滤器时,选定的旧参数都会消失。这是我的代码,
<Panel header="Status" key="status">
<Form
name="search"
action='/search'
method="get"
onChange={(e) => submit(e.currentTarget, { replace: false })}
>
<ul>
<li>
<Checkbox
name="status"
value="buy_now"
defaultChecked={status.includes('buy_now')}
>
Buy Now
</Checkbox>
</li>
<li>
<Checkbox
name="status"
value="on_auction"
defaultChecked={status.includes('on_auction')}
>
On Auction
</Checkbox>
</li>
</ul>
</Form>
</Panel>
<Panel header="Price" key="price">
<Form name="search" action='/search' method="get">
<Select
name="blockchain"
value={
blockchain
? options.filter((a) => a.value === blockchain)
: undefined
}
options={options}
placeholder="Blockchain"
type="white"
/>
<div className="d-flex align-center price">
<TextInput
value={min ? min : undefined}
name="min"
placeholder="Min"
/>
<span>to</span>
<TextInput
value={max ? max : undefined}
name="max"
placeholder="Max"
/>
</div>
<button
onClick={(e) => {
e.stopPropagation()
submit(e.currentTarget, { replace: false })
}}
className="btn primary-btn btn-lg w-100"
>
Apply
</button>
</Form>
</Panel>
我如何解决这个问题以获得所有参数,而不必使用 React 状态自行管理它们?
编辑:- 我希望第一个过滤器自动提交,而后者在单击按钮时提交。
我想要实现的 UI 一点点,
答案:在投入了足够的时间寻找捷径后,终于明白这不是remix.run的神奇之处。使用 formik 之类的东西并比较地更新状态。
当您提交表单时,包含的唯一值是提交表单下的值。不包括任何其他形式的值(幸运的是!)。
所以我会使用一个表单,其中包含所有输入(复选框和文本输入)。
然后,您可以在复选框上添加类似 onChange
处理程序的东西,而不是表单上的 onChange
并在内部强制提交表单(使用 ref 单击提交按钮或其他东西,我认为使用在表单上引用您需要在提交函数中提交所有值,因此单击引用按钮可能更简单)。
请记住,如果您想在提交后“恢复”字段值,您需要像这样从加载程序函数中 return 它们:
// Loader function
const url = new URL(request.url);
return {
results: [...],
values: Object.fromEntries(url.searchParams.entries())
};
然后在组件中,使用values
from useLoaderData
:
<input type="text" name="max" defaultValue={values.max || ""}/>
额外的好处:如果您返回此页面(例如通过单击浏览器返回),您的搜索参数和搜索结果仍然存在!
我实际上为你准备了一个 stackblitz,但我丢失了所有更改:(
您似乎可以将所有字段保存在一个表单中,然后在按下提交按钮时提交该表单。
然后 onChange,检查目标名称是否为 'status',并提交表单。
export default function App() {
const submit = (form) => {
form.submit();
};
return (
<form
name="search"
action="/search"
method="get"
onChange={(e) => {
if (e.target.name === "status") {
submit(e.currentTarget);
}
}}
>
<fieldset>
<legend>status</legend>
<label>
<input type="checkbox" name="status" value="buy_now" />
buy_now
</label>
<label>
<input type="checkbox" name="status" value="on_auction" />
on_auction
</label>
</fieldset>
<fieldset>
<legend>price</legend>
<label>
<div>blockchain</div>
<select name="blockchain">
<option value="option_1">Blockchain Option 1</option>
<option value="option_2">Blockchain Option 2</option>
</select>
</label>
<label>
min <input type="number" name="min" />
</label>
<label>
max <input type="number" name="max" />
</label>
</fieldset>
<button type="submit">Apply</button>
</form>
);
}
注意:不确定您想要将其分成不同形式的动机是什么,但我认为您指的 magic 是服务器状态、URLSearchParams、FormData和 UI 都是一致的,因为它们使用相同的基础数据,仅使用通用的 Web API。
我正在搜索 UI,其中有很多过滤器,当有人 selects/checks 选项时,我希望将其作为 URL 参数。我已经使用 Remix.run 文档中建议的技术在过滤器中提出多种形式。每次提交一组过滤器时,选定的旧参数都会消失。这是我的代码,
<Panel header="Status" key="status">
<Form
name="search"
action='/search'
method="get"
onChange={(e) => submit(e.currentTarget, { replace: false })}
>
<ul>
<li>
<Checkbox
name="status"
value="buy_now"
defaultChecked={status.includes('buy_now')}
>
Buy Now
</Checkbox>
</li>
<li>
<Checkbox
name="status"
value="on_auction"
defaultChecked={status.includes('on_auction')}
>
On Auction
</Checkbox>
</li>
</ul>
</Form>
</Panel>
<Panel header="Price" key="price">
<Form name="search" action='/search' method="get">
<Select
name="blockchain"
value={
blockchain
? options.filter((a) => a.value === blockchain)
: undefined
}
options={options}
placeholder="Blockchain"
type="white"
/>
<div className="d-flex align-center price">
<TextInput
value={min ? min : undefined}
name="min"
placeholder="Min"
/>
<span>to</span>
<TextInput
value={max ? max : undefined}
name="max"
placeholder="Max"
/>
</div>
<button
onClick={(e) => {
e.stopPropagation()
submit(e.currentTarget, { replace: false })
}}
className="btn primary-btn btn-lg w-100"
>
Apply
</button>
</Form>
</Panel>
我如何解决这个问题以获得所有参数,而不必使用 React 状态自行管理它们?
编辑:- 我希望第一个过滤器自动提交,而后者在单击按钮时提交。
我想要实现的 UI 一点点,
答案:在投入了足够的时间寻找捷径后,终于明白这不是remix.run的神奇之处。使用 formik 之类的东西并比较地更新状态。
当您提交表单时,包含的唯一值是提交表单下的值。不包括任何其他形式的值(幸运的是!)。
所以我会使用一个表单,其中包含所有输入(复选框和文本输入)。
然后,您可以在复选框上添加类似 onChange
处理程序的东西,而不是表单上的 onChange
并在内部强制提交表单(使用 ref 单击提交按钮或其他东西,我认为使用在表单上引用您需要在提交函数中提交所有值,因此单击引用按钮可能更简单)。
请记住,如果您想在提交后“恢复”字段值,您需要像这样从加载程序函数中 return 它们:
// Loader function
const url = new URL(request.url);
return {
results: [...],
values: Object.fromEntries(url.searchParams.entries())
};
然后在组件中,使用values
from useLoaderData
:
<input type="text" name="max" defaultValue={values.max || ""}/>
额外的好处:如果您返回此页面(例如通过单击浏览器返回),您的搜索参数和搜索结果仍然存在!
我实际上为你准备了一个 stackblitz,但我丢失了所有更改:(
您似乎可以将所有字段保存在一个表单中,然后在按下提交按钮时提交该表单。
然后 onChange,检查目标名称是否为 'status',并提交表单。
export default function App() {
const submit = (form) => {
form.submit();
};
return (
<form
name="search"
action="/search"
method="get"
onChange={(e) => {
if (e.target.name === "status") {
submit(e.currentTarget);
}
}}
>
<fieldset>
<legend>status</legend>
<label>
<input type="checkbox" name="status" value="buy_now" />
buy_now
</label>
<label>
<input type="checkbox" name="status" value="on_auction" />
on_auction
</label>
</fieldset>
<fieldset>
<legend>price</legend>
<label>
<div>blockchain</div>
<select name="blockchain">
<option value="option_1">Blockchain Option 1</option>
<option value="option_2">Blockchain Option 2</option>
</select>
</label>
<label>
min <input type="number" name="min" />
</label>
<label>
max <input type="number" name="max" />
</label>
</fieldset>
<button type="submit">Apply</button>
</form>
);
}
注意:不确定您想要将其分成不同形式的动机是什么,但我认为您指的 magic 是服务器状态、URLSearchParams、FormData和 UI 都是一致的,因为它们使用相同的基础数据,仅使用通用的 Web API。