React-select defaultValue 提交时未定义
React-select defaultValue is undefined when submitted
我将 react-select
用于单个 select 菜单。当我编辑表单时,defaultValue
似乎正确显示,但是当我提交表单时,如果 selection 保持不变,则返回的值为 undefined
。如果我单击 defaultValue
,那么它在提交时可以正常工作。是否有额外的 prop
我缺少通过提交来维护 defaultValue
?
代码如下所示:
<Select
closeMenuOnSelect={true}
options={options()}
defaultValue={defaultVal}
className="basic-single"
classNamePrefix="select"
/>
其中 options()
是一个简单的函数,可以像这样格式化数据:
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
和defaultVal
returns通过过滤得到单个值options
:
let defaultVal = options().filter(
(optionChoice) => optionChoice.label === props.choice
);
由于您正在使用 react-hook-form
,因此您需要利用他们的 Controller
组件在表单中注册您的 select。此处参考:Integrating Controlled Inputs.
以下组件声明说明了将 react-select
组件包装在 react-hook-form
控制器组件中。它使用 control={control}
注册到 react-hook-form,然后通过 Controller 组件的渲染属性渲染 select。
您还需要让 react-hook-form
知道 selection 何时发生变化,方法是在变化时从 select 调用 handleChange
。 handleChange()
依次用更改后的值调用 react-hook-form
的 setValue()
,并且 shouldDirty: true
标记更改。
const handleChange = (change) => {
setValue("controlledSelect", change, {
shouldDirty: true
});
};
这里的工作沙箱:https://codesandbox.io/s/react-select-with-react-hook-form-im9hi
import React from "react";
import { useForm, Controller } from "react-hook-form";
import Select from "react-select";
function ControlledSelect() {
const { handleSubmit, control, setValue } = useForm();
const [options, setOptions] = React.useState(initialOptions);
const onSubmitData = (data) => {
console.log(data);
};
const handleChange = (change) => {
setValue("controlledSelect", change, {
shouldDirty: true
});
};
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmitData)}>
<Controller
name="controlledSelect"
control={control}
defaultValue={options[1]}
render={() => (
<Select
options={options}
defaultValue={options[1]}
onChange={handleChange}
/>
)}
/>
<button type="submit">Submit Select</button>
</form>
</div>
);
}
这是一个粗略的片段,显示了一个有效的 select。看起来您想将 defaultValue
声明为数组中的索引:defaultValue={defaultVal[0]}
。这将需要在渲染之前生成格式化的选项数组而不是传递一个函数,无论如何这可能更好。
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/emotion@9.2.12/dist/emotion.umd.min.js"></script>
<script src="https://unpkg.com/prop-types@15.5.10/prop-types.min.js"></script>
<script src="https://unpkg.com/react-input-autosize@2.2.1/dist/react-input-autosize.min.js"></script>
<script src="https://unpkg.com/react-select@2.1.2/dist/react-select.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<div id="App"></div>
<script type="text/babel">
const {useRef} = React;
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
]
function App() {
const formRef = useRef();
const submitForm = (e, ref) => {
e.preventDefault();
console.log(formRef.current.elements[1].value);
}
return (
<form ref={formRef} onSubmit={submitForm}>
<Select
name="select"
options={options}
defaultValue={options[1]}
/>
<input type="submit" value="Submit" />
</form>
)
}
ReactDOM.render(<App />, document.getElementById('App'));
</script>
我将 react-select
用于单个 select 菜单。当我编辑表单时,defaultValue
似乎正确显示,但是当我提交表单时,如果 selection 保持不变,则返回的值为 undefined
。如果我单击 defaultValue
,那么它在提交时可以正常工作。是否有额外的 prop
我缺少通过提交来维护 defaultValue
?
代码如下所示:
<Select
closeMenuOnSelect={true}
options={options()}
defaultValue={defaultVal}
className="basic-single"
classNamePrefix="select"
/>
其中 options()
是一个简单的函数,可以像这样格式化数据:
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
和defaultVal
returns通过过滤得到单个值options
:
let defaultVal = options().filter(
(optionChoice) => optionChoice.label === props.choice
);
由于您正在使用 react-hook-form
,因此您需要利用他们的 Controller
组件在表单中注册您的 select。此处参考:Integrating Controlled Inputs.
以下组件声明说明了将 react-select
组件包装在 react-hook-form
控制器组件中。它使用 control={control}
注册到 react-hook-form,然后通过 Controller 组件的渲染属性渲染 select。
您还需要让 react-hook-form
知道 selection 何时发生变化,方法是在变化时从 select 调用 handleChange
。 handleChange()
依次用更改后的值调用 react-hook-form
的 setValue()
,并且 shouldDirty: true
标记更改。
const handleChange = (change) => {
setValue("controlledSelect", change, {
shouldDirty: true
});
};
这里的工作沙箱:https://codesandbox.io/s/react-select-with-react-hook-form-im9hi
import React from "react";
import { useForm, Controller } from "react-hook-form";
import Select from "react-select";
function ControlledSelect() {
const { handleSubmit, control, setValue } = useForm();
const [options, setOptions] = React.useState(initialOptions);
const onSubmitData = (data) => {
console.log(data);
};
const handleChange = (change) => {
setValue("controlledSelect", change, {
shouldDirty: true
});
};
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmitData)}>
<Controller
name="controlledSelect"
control={control}
defaultValue={options[1]}
render={() => (
<Select
options={options}
defaultValue={options[1]}
onChange={handleChange}
/>
)}
/>
<button type="submit">Submit Select</button>
</form>
</div>
);
}
这是一个粗略的片段,显示了一个有效的 select。看起来您想将 defaultValue
声明为数组中的索引:defaultValue={defaultVal[0]}
。这将需要在渲染之前生成格式化的选项数组而不是传递一个函数,无论如何这可能更好。
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/emotion@9.2.12/dist/emotion.umd.min.js"></script>
<script src="https://unpkg.com/prop-types@15.5.10/prop-types.min.js"></script>
<script src="https://unpkg.com/react-input-autosize@2.2.1/dist/react-input-autosize.min.js"></script>
<script src="https://unpkg.com/react-select@2.1.2/dist/react-select.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<div id="App"></div>
<script type="text/babel">
const {useRef} = React;
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
]
function App() {
const formRef = useRef();
const submitForm = (e, ref) => {
e.preventDefault();
console.log(formRef.current.elements[1].value);
}
return (
<form ref={formRef} onSubmit={submitForm}>
<Select
name="select"
options={options}
defaultValue={options[1]}
/>
<input type="submit" value="Submit" />
</form>
)
}
ReactDOM.render(<App />, document.getElementById('App'));
</script>