如何防止 ReactSelect 清除输入?
How to prevent ReactSelect from clearing the input?
我的应用程序中的 ReactSelect 组件在我进行选择后清除我输入的内容。我不希望它那样做。
我希望它保持原样。当用户没有输入任何内容时,我希望它显示占位符文本。
我将此组件用作搜索框。从列表中选择一项即可完成任务。没有理由将组件的值设置为选择。
react-select
不支持开箱即用的自动完成功能,因此需要一些额外的工作和技巧才能获得您想要的内容。
首先,你需要控制inputValue
状态,menu-close
或set-value
等一些操作之后会清除输入。
const [input, setInput] = React.useState("");
const handleInputChange = (e, meta) => {
if (meta.action === "input-change") {
setInput(e);
}
};
return (
<Select
value={selected}
onChange={handleChange}
inputValue={input}
isSearchable
{...}
/>
);
react-select
还会在选择选项后隐藏输入,因此您还需要覆盖该行为。
const [selected, setSelected] = React.useState([]);
const handleChange = (s) => {
setSelected({ ...s });
};
React.useLayoutEffect(() => {
const inputEl = document.getElementById("myInput");
if (!inputEl) return;
// prevent input from being hidden after selecting
inputEl.style.opacity = "1";
}, [selected]);
return (
<Select
value={selected}
inputId="myInput"
onChange={handleChange}
{...}
/>
);
最后但同样重要的是,您可能希望在成功选择后相应地更新您的输入,这是一个基本示例,下面的代码将在选择后将新的选项值附加到您当前的输入。
同时确保重写默认值 filterOption
以在过滤时仅考虑最后一个词,否则前几个词后的选项将不匹配任何内容。
const [selected, setSelected] = React.useState([]);
const [input, setInput] = React.useState("");
const handleChange = (s) => {
setSelected({ ...s });
setInput((input) => removeLastWord(input) + s.value);
};
const customFilter = () => {
return (config, rawInput) => {
const filter = createFilter(null);
return filter(config, getLastWord(rawInput));
};
};
return (
<Select
value={selected}
filterOption={customFilter()}
onChange={handleChange}
inputValue={input}
components={{
SingleValue: () => null
}}
{...}
/>
);
其中 removeLastWord
和 getLastWord
只是一些实用函数。
function getLastWord(str: string) {
return str.split(" ").slice(-1).pop();
}
function removeLastWord(str: string) {
var lastWhiteSpaceIndex = str.lastIndexOf(" ");
return str.substring(0, lastWhiteSpaceIndex + 1);
}
这是结合以上所有内容后的完整示例。
import React from "react";
import Select, { components, createFilter } from "react-select";
import options from "./options";
function getLastWord(str: string) {
return str.split(" ").slice(-1).pop();
}
function removeLastWord(str: string) {
var lastWhiteSpaceIndex = str.lastIndexOf(" ");
return str.substring(0, lastWhiteSpaceIndex + 1);
}
export default function MySelect() {
const [selected, setSelected] = React.useState([]);
const [input, setInput] = React.useState("");
const handleChange = (s) => {
setSelected({ ...s });
setInput((input) => removeLastWord(input) + s.value);
};
const handleInputChange = (e, meta) => {
if (meta.action === "input-change") {
setInput(e);
}
};
React.useLayoutEffect(() => {
const inputEl = document.getElementById("myInput");
if (!inputEl) return;
// prevent input from being hidden after selecting
inputEl.style.opacity = "1";
}, [selected]);
const customFilter = () => {
return (config, rawInput) => {
const filter = createFilter(null);
return filter(config, getLastWord(rawInput));
};
};
return (
<Select
value={selected}
filterOption={customFilter()}
inputId="myInput"
onChange={handleChange}
blurInputOnSelect={false}
inputValue={input}
onInputChange={handleInputChange}
options={options}
isSearchable
hideSelectedOptions={false}
components={{
SingleValue: () => null
}}
/>
);
}
实例
您还可以使用 styles
道具覆盖输入样式。在这个 thread
上有关于这个问题的完整讨论
{
input: (provided) => ({
...provided,
input: {
opacity: "1 !important",
},
}),
}
我的应用程序中的 ReactSelect 组件在我进行选择后清除我输入的内容。我不希望它那样做。
我希望它保持原样。当用户没有输入任何内容时,我希望它显示占位符文本。
我将此组件用作搜索框。从列表中选择一项即可完成任务。没有理由将组件的值设置为选择。
react-select
不支持开箱即用的自动完成功能,因此需要一些额外的工作和技巧才能获得您想要的内容。
首先,你需要控制inputValue
状态,menu-close
或set-value
等一些操作之后会清除输入。
const [input, setInput] = React.useState("");
const handleInputChange = (e, meta) => {
if (meta.action === "input-change") {
setInput(e);
}
};
return (
<Select
value={selected}
onChange={handleChange}
inputValue={input}
isSearchable
{...}
/>
);
react-select
还会在选择选项后隐藏输入,因此您还需要覆盖该行为。
const [selected, setSelected] = React.useState([]);
const handleChange = (s) => {
setSelected({ ...s });
};
React.useLayoutEffect(() => {
const inputEl = document.getElementById("myInput");
if (!inputEl) return;
// prevent input from being hidden after selecting
inputEl.style.opacity = "1";
}, [selected]);
return (
<Select
value={selected}
inputId="myInput"
onChange={handleChange}
{...}
/>
);
最后但同样重要的是,您可能希望在成功选择后相应地更新您的输入,这是一个基本示例,下面的代码将在选择后将新的选项值附加到您当前的输入。
同时确保重写默认值 filterOption
以在过滤时仅考虑最后一个词,否则前几个词后的选项将不匹配任何内容。
const [selected, setSelected] = React.useState([]);
const [input, setInput] = React.useState("");
const handleChange = (s) => {
setSelected({ ...s });
setInput((input) => removeLastWord(input) + s.value);
};
const customFilter = () => {
return (config, rawInput) => {
const filter = createFilter(null);
return filter(config, getLastWord(rawInput));
};
};
return (
<Select
value={selected}
filterOption={customFilter()}
onChange={handleChange}
inputValue={input}
components={{
SingleValue: () => null
}}
{...}
/>
);
其中 removeLastWord
和 getLastWord
只是一些实用函数。
function getLastWord(str: string) {
return str.split(" ").slice(-1).pop();
}
function removeLastWord(str: string) {
var lastWhiteSpaceIndex = str.lastIndexOf(" ");
return str.substring(0, lastWhiteSpaceIndex + 1);
}
这是结合以上所有内容后的完整示例。
import React from "react";
import Select, { components, createFilter } from "react-select";
import options from "./options";
function getLastWord(str: string) {
return str.split(" ").slice(-1).pop();
}
function removeLastWord(str: string) {
var lastWhiteSpaceIndex = str.lastIndexOf(" ");
return str.substring(0, lastWhiteSpaceIndex + 1);
}
export default function MySelect() {
const [selected, setSelected] = React.useState([]);
const [input, setInput] = React.useState("");
const handleChange = (s) => {
setSelected({ ...s });
setInput((input) => removeLastWord(input) + s.value);
};
const handleInputChange = (e, meta) => {
if (meta.action === "input-change") {
setInput(e);
}
};
React.useLayoutEffect(() => {
const inputEl = document.getElementById("myInput");
if (!inputEl) return;
// prevent input from being hidden after selecting
inputEl.style.opacity = "1";
}, [selected]);
const customFilter = () => {
return (config, rawInput) => {
const filter = createFilter(null);
return filter(config, getLastWord(rawInput));
};
};
return (
<Select
value={selected}
filterOption={customFilter()}
inputId="myInput"
onChange={handleChange}
blurInputOnSelect={false}
inputValue={input}
onInputChange={handleInputChange}
options={options}
isSearchable
hideSelectedOptions={false}
components={{
SingleValue: () => null
}}
/>
);
}
实例
您还可以使用 styles
道具覆盖输入样式。在这个 thread
{
input: (provided) => ({
...provided,
input: {
opacity: "1 !important",
},
}),
}