如何在使用反应钩子形式反应 select 一段时间后设置默认值
How to set defaultValue after some delay on react select with react hook form
我正在使用 react-select 下拉菜单和 react-hook-form 库。我正在调用 api 来获取 react-select 的默认值。最初下拉列表无法预填充默认值。所以我找到了一个解决方法,当我从 api.
获取数据时重新渲染整个 JSX
<form onSubmit={handleSubmit(saveData)}>
{!countryValue && (
<Controller
name="country"
control={control}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={country.find((c) => c.value === value)}
onChange={(val) => onChange(val.value)}
/>
)}
rules={{ required: true }}
/>
)}
{countryValue && (
<Controller
name="country"
control={control}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={country.find((c) => c.value === value)}
onChange={(val) => onChange(val.value)}
defaultValue={country.find((c) => c.value === countryValue)}
/>
)}
rules={{ required: true }}
/>
)}
{errors.country && <div>Field is rquired</div>}
<button type="submit">Save</button>
</form>
我在 countryValue 上设置了一个条件,即当组件获取 countryValue 的值时,它会呈现整个下拉列表。
但是当我使用相同的 defaultValue 钩子表单提交表单时,出现国家字段未定义的错误。
我为此创建了一个沙箱。
https://codesandbox.io/s/react-select-with-react-hook-form-sc2xz
如何解决这个问题。他们有什么解决方法吗?
一个很好的问题,但看起来你做的有点乱,
您将国家/地区对象传递给 Select 组件,然后在 value
和 onChange
道具 中再次过滤它(为什么,我想不通? ),
首先你需要为你的Select组件定义一个defaultValue
,但是你不能在同一个地方同时使用(defaultValue
和 value
),做使用控制器为您设置默认值,您已经在 countryValue 状态中定义:
import "./styles.css";
import Select from "react-select";
import { useForm, Controller } from "react-hook-form";
import { useEffect, useState } from "react";
let country = [
{ label: "Bangladesh", value: "Bangladesh" },
{ label: "India", value: "India" },
{ label: "China", value: "China" },
{ label: "Finland", value: "Finland" }
];
export default function App() {
const [countryValue, setCountryValue] = useState({
label: "India",
value: "India"
});
const { handleSubmit, control, errors } = useForm();
useEffect(() => {
setTimeout(() => {
setCountryValue("India");
}, 2000);
}, []);
useEffect(() => {
console.log("errors", errors);
}, [errors]);
const saveData = (form_data) => {
console.log("form_data", form_data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(saveData)}>
<Controller
name="country"
control={control}
defaultValue={countryValue}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={value}
onChange={(val) => onChange(val)}
/>
)}
rules={{ required: true }}
/>
{errors.country && <div>Field is rquired</div>}
<button type="submit">Save</button>
</form>
</div>
);
}
我认为与其重新创建一个新的组件来给它一个默认值,不如直接在现有组件上设置值。
为此,您可以使用从 useForm()
返回的对象中获得的 setValue
。
这是代码的一部分:
const { handleSubmit, control, errors, setValue } = useForm();
useEffect(() => {
setTimeout(() => {
setValue("country", "India");
}, 2000);
}, [setValue]);
就我而言,我是这样处理的
const [categories, setCategories] = useState([]);
const [defaultCategory, setDefaultCategory] = useState(null);
useEffect(() => {
if(formAction === 'UPDATE') {
setDefaultCategory(categories.find(element => element.value === data.category_id));
}
}, [categories]);
<Controller
control={control}
name="category_id"
render={({
field: { onChange, onBlur, value, name, ref },
}) => {
return(
<Select
value={defaultCategory}
onBlur={onBlur}
options={categories}
placeholder="Select a category"
defaultOptions={true}
onChange={(val) => {
setDefaultCategory(val);
onChange(val);
}}
isSearchable={false}
className="
shadow-sm
focus:ring-indigo-500
focus:border-indigo-500
block
max-w-full
text-md
border-gray-300
rounded-md
"
/>
);
}}
/> />
我正在使用 react-select 下拉菜单和 react-hook-form 库。我正在调用 api 来获取 react-select 的默认值。最初下拉列表无法预填充默认值。所以我找到了一个解决方法,当我从 api.
获取数据时重新渲染整个 JSX<form onSubmit={handleSubmit(saveData)}>
{!countryValue && (
<Controller
name="country"
control={control}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={country.find((c) => c.value === value)}
onChange={(val) => onChange(val.value)}
/>
)}
rules={{ required: true }}
/>
)}
{countryValue && (
<Controller
name="country"
control={control}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={country.find((c) => c.value === value)}
onChange={(val) => onChange(val.value)}
defaultValue={country.find((c) => c.value === countryValue)}
/>
)}
rules={{ required: true }}
/>
)}
{errors.country && <div>Field is rquired</div>}
<button type="submit">Save</button>
</form>
我在 countryValue 上设置了一个条件,即当组件获取 countryValue 的值时,它会呈现整个下拉列表。
但是当我使用相同的 defaultValue 钩子表单提交表单时,出现国家字段未定义的错误。
我为此创建了一个沙箱。 https://codesandbox.io/s/react-select-with-react-hook-form-sc2xz
如何解决这个问题。他们有什么解决方法吗?
一个很好的问题,但看起来你做的有点乱,
您将国家/地区对象传递给 Select 组件,然后在 value
和 onChange
道具 中再次过滤它(为什么,我想不通? ),
首先你需要为你的Select组件定义一个defaultValue
,但是你不能在同一个地方同时使用(defaultValue
和 value
),做使用控制器为您设置默认值,您已经在 countryValue 状态中定义:
import "./styles.css";
import Select from "react-select";
import { useForm, Controller } from "react-hook-form";
import { useEffect, useState } from "react";
let country = [
{ label: "Bangladesh", value: "Bangladesh" },
{ label: "India", value: "India" },
{ label: "China", value: "China" },
{ label: "Finland", value: "Finland" }
];
export default function App() {
const [countryValue, setCountryValue] = useState({
label: "India",
value: "India"
});
const { handleSubmit, control, errors } = useForm();
useEffect(() => {
setTimeout(() => {
setCountryValue("India");
}, 2000);
}, []);
useEffect(() => {
console.log("errors", errors);
}, [errors]);
const saveData = (form_data) => {
console.log("form_data", form_data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(saveData)}>
<Controller
name="country"
control={control}
defaultValue={countryValue}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={value}
onChange={(val) => onChange(val)}
/>
)}
rules={{ required: true }}
/>
{errors.country && <div>Field is rquired</div>}
<button type="submit">Save</button>
</form>
</div>
);
}
我认为与其重新创建一个新的组件来给它一个默认值,不如直接在现有组件上设置值。
为此,您可以使用从 useForm()
返回的对象中获得的 setValue
。
这是代码的一部分:
const { handleSubmit, control, errors, setValue } = useForm();
useEffect(() => {
setTimeout(() => {
setValue("country", "India");
}, 2000);
}, [setValue]);
就我而言,我是这样处理的
const [categories, setCategories] = useState([]);
const [defaultCategory, setDefaultCategory] = useState(null);
useEffect(() => {
if(formAction === 'UPDATE') {
setDefaultCategory(categories.find(element => element.value === data.category_id));
}
}, [categories]);
<Controller
control={control}
name="category_id"
render={({
field: { onChange, onBlur, value, name, ref },
}) => {
return(
<Select
value={defaultCategory}
onBlur={onBlur}
options={categories}
placeholder="Select a category"
defaultOptions={true}
onChange={(val) => {
setDefaultCategory(val);
onChange(val);
}}
isSearchable={false}
className="
shadow-sm
focus:ring-indigo-500
focus:border-indigo-500
block
max-w-full
text-md
border-gray-300
rounded-md
"
/>
);
}}
/> />