react-select Creatable:转换创建的选项
react-select Creatable: transforming created options
我尝试使用 react-select's Creatable select 组件来允许用户添加多个 CORS 源以注册到我的身份验证服务器。我希望能够允许用户粘贴完整的 URLs,并在将这些 URLs 添加到 Creatable [=] 后将其转换为 Origins(格式:<protocol>://<origin>[:port]
) 37=].
例如,用户可以将 http://some-domain.com:1234/management/clients?param1=abc¶m2=123#fragment_stuff
粘贴到 Creatable select 中,整个 URL 将自动成为 converted/added 作为其原始组件:http://some-domain.com:1234
.
这是我编写的组件 (TypeScript) 的简化版本:
import CreatableSelect from 'react-select/creatable';
...
type MyOptionType = {
label: string,
value: string,
}
function SomeComponent(props:{}) {
const [options, setOptions] = useState<MyOptionType[]>([]);
const onOptionsChanged = (newOptions: OptionsType<MyOptionType>) => {
// Get only options containing valid URLs, with valid origins
const validUrlsWithOrigins = newOptions.filter(option => {
try {
return !!(new URL(option.value).origin);
} catch (error) {
return false;
}
});
// Transform options (e.g.: "http://some-domain.com:1234/abc?def=ghi#jkl" will become "http://some-domain.com:1234")
const newOptionsOrigins = validUrlsWithOrigins
.map(option => new URL(option.value).origin)
.map(origin => ({label: origin, value: origin}));
setOptions(newOptionsOrigins);
}
return <CreatableSelect isMulti options={options} onChange={onOptionsChanged} />
}
在使用 React Developer Tools 进行调试时,我可以看到组件的状态正在相应地进行转换,只有 URLs 的 origin 部分是保持状态:
问题是 Creatable select 组件正在呈现完整的 URL 而不是仅呈现 URL 的来源:
为什么 Creatable select 与组件的状态不同步?有没有办法解决这个问题,或者是对 react-select?
的限制
你需要在这里区分两件事 - options
CreatableSelect
的属性包含所有可能性的数组。但是这个组件的值是由 value
属性.
管理的
您可以查看 Multi-select text input
示例 on docs page 但基本上您需要:
单独保留值和选项:
const [options, setOptions] = React.useState<MyOptionType[]>([]);
const [value, setValue] = React.useState<MyOptionType[]>([]);
const createOption = (label: string) => ({
label,
value: label
});
<CreatableSelect
isMulti
options={options}
value={options}
onChange={onOptionsChanged}
/>
并修改您的 onOptionsChanged
函数
- 设置
value
已转换和验证的输入
- 向
options
状态变量添加新选项(所有选项,无重复项)
这里有一些例子:
// Transform options (e.g.: "http://some-domain.com:1234/abc?def=ghi#jkl" will become "http://some-domain.com:1234")
const newOptionsOrigins = validUrlsWithOrigins
.map((option) => new URL(option.value).origin)
.map((origin) => createOption(origin));
setValue(newOptionsOrigins);
//get all options without duplicates
const allUniqueOptions: object = {};
[...newOptionsOrigins, ...options].forEach((option) => {
allUniqueOptions[option.value] = option.value;
});
setOptions(
Object.keys(allUniqueOptions).map((option) => createOption(option))
);
};
我尝试使用 react-select's Creatable select 组件来允许用户添加多个 CORS 源以注册到我的身份验证服务器。我希望能够允许用户粘贴完整的 URLs,并在将这些 URLs 添加到 Creatable [=] 后将其转换为 Origins(格式:<protocol>://<origin>[:port]
) 37=].
例如,用户可以将 http://some-domain.com:1234/management/clients?param1=abc¶m2=123#fragment_stuff
粘贴到 Creatable select 中,整个 URL 将自动成为 converted/added 作为其原始组件:http://some-domain.com:1234
.
这是我编写的组件 (TypeScript) 的简化版本:
import CreatableSelect from 'react-select/creatable';
...
type MyOptionType = {
label: string,
value: string,
}
function SomeComponent(props:{}) {
const [options, setOptions] = useState<MyOptionType[]>([]);
const onOptionsChanged = (newOptions: OptionsType<MyOptionType>) => {
// Get only options containing valid URLs, with valid origins
const validUrlsWithOrigins = newOptions.filter(option => {
try {
return !!(new URL(option.value).origin);
} catch (error) {
return false;
}
});
// Transform options (e.g.: "http://some-domain.com:1234/abc?def=ghi#jkl" will become "http://some-domain.com:1234")
const newOptionsOrigins = validUrlsWithOrigins
.map(option => new URL(option.value).origin)
.map(origin => ({label: origin, value: origin}));
setOptions(newOptionsOrigins);
}
return <CreatableSelect isMulti options={options} onChange={onOptionsChanged} />
}
在使用 React Developer Tools 进行调试时,我可以看到组件的状态正在相应地进行转换,只有 URLs 的 origin 部分是保持状态:
问题是 Creatable select 组件正在呈现完整的 URL 而不是仅呈现 URL 的来源:
为什么 Creatable select 与组件的状态不同步?有没有办法解决这个问题,或者是对 react-select?
的限制你需要在这里区分两件事 - options
CreatableSelect
的属性包含所有可能性的数组。但是这个组件的值是由 value
属性.
您可以查看 Multi-select text input
示例 on docs page 但基本上您需要:
单独保留值和选项:
const [options, setOptions] = React.useState<MyOptionType[]>([]);
const [value, setValue] = React.useState<MyOptionType[]>([]);
const createOption = (label: string) => ({
label,
value: label
});
<CreatableSelect
isMulti
options={options}
value={options}
onChange={onOptionsChanged}
/>
并修改您的 onOptionsChanged
函数
- 设置
value
已转换和验证的输入 - 向
options
状态变量添加新选项(所有选项,无重复项)
这里有一些例子:
// Transform options (e.g.: "http://some-domain.com:1234/abc?def=ghi#jkl" will become "http://some-domain.com:1234")
const newOptionsOrigins = validUrlsWithOrigins
.map((option) => new URL(option.value).origin)
.map((origin) => createOption(origin));
setValue(newOptionsOrigins);
//get all options without duplicates
const allUniqueOptions: object = {};
[...newOptionsOrigins, ...options].forEach((option) => {
allUniqueOptions[option.value] = option.value;
});
setOptions(
Object.keys(allUniqueOptions).map((option) => createOption(option))
);
};