admin管理员组文章数量:1287866
I'm trying to build a form using React with select elements from react-select and the validation done using react-hook-form.
Upon change the value seems to successfully change, but when I submit the form the select value is undefined.
I have input fields and those work properly, but for my select and multi-select elements it fails.
New to React so very confused, tried to find an answer to this but not able to. Removed some of the code to keep the interesting parts, hopefully I got it right.
import React, { useState } from "react";
import Collapsible from "../collapsible/Collapsible"
import Select, { ponents } from 'react-select';
import axios from "axios";
import { useInput } from "../../hooks"
import { useForm } from 'react-hook-form';
import { selectStyles } from "./styles"
import allBots from "../../data/bots";
import platforms from "../../data/platforms";
import connectionTypes from "../../data/connection_types";
import generatePayload from "./generate_payload";
const Connect = () => {
const { setValue, register, handleSubmit, errors } = useForm();
const [values, setValues] = useState({
selectedOption: []
});
const CustomOption = props => {
return (
<ponents.Option {...props}>
<div style={{ display: "inline-block", "min-width": "40px" }}>{props.data.suffix}</div>
<div style={{ display: "inline-block" }}>{props.data.value}</div>
</ponents.Option>
);
};
const handleBotChange = selectedBot => {
setValue("bots", selectedBot);
setValues(selectedBot);
};
const handleMultiChange = selectedOption => {
console.log(selectedOption);
setValue("platform", selectedOption);
setValues(selectedOption);
};
const onSubmit = (data) => {
console.log(data);
// outputs { "bots": undefined, "platform": undefined, username: "theinput" }
}
return (
<Collapsible className="collapsible" header="Connect">
<div className="collapsibleContent">
<form onSubmit={handleSubmit(onSubmit)}>
<Select
className="reactSelect"
name="platform"
placeholder="Platform"
value={values.platform}
onChange={handleMultiChange}
options={platforms}
ref={e => register({ name: "platform", required: true })}
/>
<Select
isMulti
name="bots"
options={bots}
onChange={handleBotChange}
closeMenuOnSelect={false}
blurInputOnSelect={false}
className="basic-multi-select formItem"
classNamePrefix="select"
ponents={{Option: CustomOption}}
styles={selectStyles}
placeholder="Bots"
ref={e => register({ name: "bots", required: true })}
/>
<input
name="username"
ref={register({
validate: value => value !== "illegal_value" || "Illegal value"
})}
/>
{errors.username && errors.username.message}
<button type="submit">Submit</button>
</form>
</div>
</Collapsible>
);
}
export default Connect;
Update: I decided to use the "Controller" functionality of react-hook-form to integrate it with react-select. This is how part my code ended up. I also use SocketIO events in order to dynamically populate the options in the dropdown list. This solution isn't perfect but it's something.
import React, { useState, useEffect } from "react";
import Collapsible from "../collapsible/Collapsible"
import Select, { ponents } from 'react-select';
import { useForm, Controller } from 'react-hook-form';
import { selectStyles } from "./styles"
import connectionTypes from "../../data/connection_types";
import { OptionWithSuffix } from "../form_ponents/ponents";
import socket from "../socket";
const Connect = () => {
const { errors, control, watch, getValues, handleSubmit, register, setValue, reset } = useForm();
const watchFields = watch(["connectionType"]);
const [bots, setBots] = useState([]);
const connectionType = getValues("connectionType") || {};
useEffect(() => {
socket.on("bots", data => {
setBots(data.map(obj => ({...obj, suffix: obj.count, value: obj.name, label: obj.name})));
});
return () => {
socket.off("bots");
};
}, []);
const onSubmit = (data) => {
console.log(data);
}
return(
<Collapsible className="collapsible" header="Connect">
<div>
<form onSubmit={handleSubmit(data => onSubmit(data))}>
<Controller
control={control}
as={<Select className="formItem" options={platforms} />}
rules={{ required: true }}
placeholder="Select platform"
name="platform"
styles={selectStyles}
register={register}
setValue={setValue}
/>
<Controller
control={control}
as={<Select className="formItem" options={connectionTypes}/>}
rules={{ required: true}}
placeholder="Select connection type"
name="connectionType"
styles={selectStyles}
register={register}
setValue={setValue}
/>
{errors.connectionType && "Connection type is required"}
{connectionType.value === "specific" &&
<Controller
control={control}
as={
<Select
isMulti
className="formItem"
options={bots}
closeMenuOnBlur={false}
closeMenuOnSelect={false}
ponents={{Option: OptionWithSuffix}}
styles={selectStyles}
/>
}
rules={{ required: true }}
placeholder="Select bots"
name="bots"
rules={{ required: true }}
register={register}
setValue={setValue}
/>
}
{errors.platform && connectionType.value === "specific" && "Bots are required"}
<input className="formItem" type="submit" placeholder="Connect"/>
</form>
</div>
</Collapsible>
);
}
export default Connect;
I'm trying to build a form using React with select elements from react-select and the validation done using react-hook-form.
Upon change the value seems to successfully change, but when I submit the form the select value is undefined.
I have input fields and those work properly, but for my select and multi-select elements it fails.
New to React so very confused, tried to find an answer to this but not able to. Removed some of the code to keep the interesting parts, hopefully I got it right.
import React, { useState } from "react";
import Collapsible from "../collapsible/Collapsible"
import Select, { ponents } from 'react-select';
import axios from "axios";
import { useInput } from "../../hooks"
import { useForm } from 'react-hook-form';
import { selectStyles } from "./styles"
import allBots from "../../data/bots";
import platforms from "../../data/platforms";
import connectionTypes from "../../data/connection_types";
import generatePayload from "./generate_payload";
const Connect = () => {
const { setValue, register, handleSubmit, errors } = useForm();
const [values, setValues] = useState({
selectedOption: []
});
const CustomOption = props => {
return (
<ponents.Option {...props}>
<div style={{ display: "inline-block", "min-width": "40px" }}>{props.data.suffix}</div>
<div style={{ display: "inline-block" }}>{props.data.value}</div>
</ponents.Option>
);
};
const handleBotChange = selectedBot => {
setValue("bots", selectedBot);
setValues(selectedBot);
};
const handleMultiChange = selectedOption => {
console.log(selectedOption);
setValue("platform", selectedOption);
setValues(selectedOption);
};
const onSubmit = (data) => {
console.log(data);
// outputs { "bots": undefined, "platform": undefined, username: "theinput" }
}
return (
<Collapsible className="collapsible" header="Connect">
<div className="collapsibleContent">
<form onSubmit={handleSubmit(onSubmit)}>
<Select
className="reactSelect"
name="platform"
placeholder="Platform"
value={values.platform}
onChange={handleMultiChange}
options={platforms}
ref={e => register({ name: "platform", required: true })}
/>
<Select
isMulti
name="bots"
options={bots}
onChange={handleBotChange}
closeMenuOnSelect={false}
blurInputOnSelect={false}
className="basic-multi-select formItem"
classNamePrefix="select"
ponents={{Option: CustomOption}}
styles={selectStyles}
placeholder="Bots"
ref={e => register({ name: "bots", required: true })}
/>
<input
name="username"
ref={register({
validate: value => value !== "illegal_value" || "Illegal value"
})}
/>
{errors.username && errors.username.message}
<button type="submit">Submit</button>
</form>
</div>
</Collapsible>
);
}
export default Connect;
Update: I decided to use the "Controller" functionality of react-hook-form to integrate it with react-select. This is how part my code ended up. I also use SocketIO events in order to dynamically populate the options in the dropdown list. This solution isn't perfect but it's something.
import React, { useState, useEffect } from "react";
import Collapsible from "../collapsible/Collapsible"
import Select, { ponents } from 'react-select';
import { useForm, Controller } from 'react-hook-form';
import { selectStyles } from "./styles"
import connectionTypes from "../../data/connection_types";
import { OptionWithSuffix } from "../form_ponents/ponents";
import socket from "../socket";
const Connect = () => {
const { errors, control, watch, getValues, handleSubmit, register, setValue, reset } = useForm();
const watchFields = watch(["connectionType"]);
const [bots, setBots] = useState([]);
const connectionType = getValues("connectionType") || {};
useEffect(() => {
socket.on("bots", data => {
setBots(data.map(obj => ({...obj, suffix: obj.count, value: obj.name, label: obj.name})));
});
return () => {
socket.off("bots");
};
}, []);
const onSubmit = (data) => {
console.log(data);
}
return(
<Collapsible className="collapsible" header="Connect">
<div>
<form onSubmit={handleSubmit(data => onSubmit(data))}>
<Controller
control={control}
as={<Select className="formItem" options={platforms} />}
rules={{ required: true }}
placeholder="Select platform"
name="platform"
styles={selectStyles}
register={register}
setValue={setValue}
/>
<Controller
control={control}
as={<Select className="formItem" options={connectionTypes}/>}
rules={{ required: true}}
placeholder="Select connection type"
name="connectionType"
styles={selectStyles}
register={register}
setValue={setValue}
/>
{errors.connectionType && "Connection type is required"}
{connectionType.value === "specific" &&
<Controller
control={control}
as={
<Select
isMulti
className="formItem"
options={bots}
closeMenuOnBlur={false}
closeMenuOnSelect={false}
ponents={{Option: OptionWithSuffix}}
styles={selectStyles}
/>
}
rules={{ required: true }}
placeholder="Select bots"
name="bots"
rules={{ required: true }}
register={register}
setValue={setValue}
/>
}
{errors.platform && connectionType.value === "specific" && "Bots are required"}
<input className="formItem" type="submit" placeholder="Connect"/>
</form>
</div>
</Collapsible>
);
}
export default Connect;
Share
Improve this question
edited Jul 28, 2020 at 18:31
Eken
asked Jul 25, 2020 at 11:55
EkenEken
1031 gold badge1 silver badge12 bronze badges
3 Answers
Reset to default 3Here's how I made my MUI-Select take multiple values using react-hook-forms in v6.14.1
.
<Controller
name="categories"
type="select"
control={control}
defaultValue={categoryOptions[0]}
render={({ onChange, onBlur, value }) => (
<RHFSelect
onChange={onChange}
onBlur={onBlur}
value={[...value]} // this is what you need to do
multiple={true}
options={categoryOptions}
/>
)}
/>
RHFSelect
is a reusable Select
in my code. To select only a single value, you may do to like this -
value={value}
For v7.9.0
, it can be done like this
<Controller
name="colors"
type="select"
control={control}
defaultValue={[]}
render={({ field }) => (
<Select
{...field}
multiple
>
/* Select ops */
</Select>
)}
/>
I cant quite test your code, since it has a few imports.
From what I can see, you will need to get the selected option value on the change event.
const handleBotChange = selectedBot => {
setValue("bots", selectedBot.value);
};
const handleMultiChange = selectedOption => {
setValue("platform", selectedOption.value);
};
Also, I do not really know the react-select control, but it might be controlled internally, so you do not need the values state hook
See here
take a look at the documentation of react-hook-form
, they show the proper way on how to register third party ui ponents, even has a example using react-select
Integrating with UI libraries
本文标签: javascriptReact hook form setValue returns undefined with multi select (reactselect)Stack Overflow
版权声明:本文标题:javascript - React hook form setValue returns undefined with multi select (react-select) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741322530a2372287.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论