英文:
How to get the value of a custom input component inside a form?
问题
我在React TypeScript中编写了一个小的自定义组件,它包装了一个带有额外功能的<input />
,主要用于在一组选项中进行模糊搜索。我计划在表单内部使用这个组件。
然而,现在我创建了这个组件,我无法在<form>
内部检索其值,因为它不是HTML元素,没有我可以读取的value
属性。
我阅读了这里的文档,但没有帮助我。我还尝试了Google搜索诸如“在React表单中的自定义输入”、“从自定义React组件获取值”等内容,但没有找到任何结果,尽管我确定这应该是许多人遇到的一个非常简单的问题。我找到的最接近的结果是这个,但答案对我没有帮助。
这是我的组件:
export interface SmartInputProps {
items: any[],
itemKey: string
//[...]
}
export const SmartInput: React.FC<SmartInputProps> = ({
items,
itemKey = 'name'
//[...]
}: SmartInputProps) => {
// [...]
//(很多功能)
return (
<div>
<input /*[...]*/ />
//一些其他可视化内容,比如显示结果列表
</div>
);
}
以及我想在其中使用该组件的表单:
interface Props {
className?: string
}
export const SearchBar: React.FC<Props> = () => {
// [...]
return (
<div className="searchbar-wrapper">
<form onSubmit={handleSubmit}>
<SmartInput
items={options}
itemKey='name'
//[...]
/>
<input type='submit' value='OK' />
</form>
</div>
);
}
我想在表单中访问位于<SmartInput />
内部的<input />
的当前value
。我尝试使用一些hacky的方法来获取这个值,比如将<input />
的onChange
委托给上层(正如这里提出的),但这只允许我在每次onChange
触发时获取并存储该值,而不是在提交时读取它。这种解决方法确实允许我在提交时使用该值,但我必须首先处理每个onChange
,这不是最佳方法。
英文:
I wrote a small custom component in react-ts that wraps an <input />
with some additional functionality, mainly fuzzy searching through a list of options. I am planning to use this inside a form.
However now that I created the component, I can not retrieve its value inside a <form>
, since it is not a html element and has no value
attribute that i can read.
I am reading the docs here, but it is not helping me. I also tried googling things like "custom input in react form", "get value from custom react component" etc. but could not find any results, although I am sure this should be a pretty straight-forward thing happening to a lot of people. the closest result I could find was this and the answers did not help me at all.
the component:
export interface SmartInputProps {
items: any[],
itemKey: string
//[...]
}
export const SmartInput: React.FC<SmartInputProps> = ({
items,
itemKey = 'name'
//[...]
}: SmartInputProps) => {
// [...]
// (lots of funcionality)
return (
<div>
<input /*[...]*/ />
//some more visual stuff, like displaying list of results
</div>
);
}
And the form I want to use the component in
interface Props {
className?: string
}
export const SearchBar: React.FC<Props> = () => {
// [...]
return (
<div className="searchbar-wrapper">
<form onSubmit={handleSubmit}>
<SmartInput
items={options}
itemKey='name'
//[...]
/>
<input type='submit' value='OK' />
</form>
</div>
);
}
I would like to access the current value
of the <input />
that is inside <SmartInput />
in the form.
I tried using hacky ways of getting the value, such as delegating the onChange
of the <input />
upwards (as proposed here), but that only allows me to get and store the value whenever onChange
is triggered, not read it at submit-time. This workaround does allow me to use the value at submit-time but I have to handle every single onChange
first which is sub-optimal.
答案1
得分: 0
我找到了一个更好的解决方案,使用 useRef
,这也更加优雅。
使用最初的示例:
interface Props {
className?: string
}
export const SearchBar: React.FC<Props> = () => {
const inputRef = useRef<HTMLInputElement>(null); // 在这里
// [...]
return (
<div className="searchbar-wrapper">
<form onSubmit={handleSubmit}>
<SmartInput
items={options}
itemKey='name'
ref={inputRef} // 在这里
//[...]
/>
<input type='submit' value='OK' />
</form>
</div>
);
}
我们向组件添加了一个带有输入类型接口的 useRef
。然后,将其作为属性传递给自定义组件 <SmartInput />
。
在接收组件的一侧:
export interface SmartInputProps {
items: any[],
itemKey: string,
ref: MutableRefObject<HTMLInputElement> // 在这里
//[...]
}
export const SmartInput: React.FC<SmartInputProps> = ({
items,
itemKey = 'name',
ref, // 在这里
//[...]
}: SmartInputProps) => {
// [...]
// (很多功能)
return (
<div>
<input ref={ref} /* 在这里 */ /*[...]*/ />
//一些其他可视化内容,如显示结果列表
</div>
);
}
我们将引用添加到自定义组件的属性,并将其传递给自定义组件内部的原生HTML输入字段的 ref
属性。
现在,我们可以从根引用对象查询字段状态。
例如:let fieldValue = inputRef.current.value
。
英文:
I found a better solution using useRef
which is also more elegant.
Using the initial examples:
interface Props {
className?: string
}
export const SearchBar: React.FC<Props> = () => {
const inputRef = useRef<HTMLInputElement>(null); //<- here
// [...]
return (
<div className="searchbar-wrapper">
<form onSubmit={handleSubmit}>
<SmartInput
items={options}
itemKey='name'
ref={inputRef} //<- here
//[...]
/>
<input type='submit' value='OK' />
</form>
</div>
);
}
We add a useRef
with the input type interface to the component. then we pass it to the custom component <SmartInput />
as a prop.
On the side of the receiving component:
export interface SmartInputProps {
items: any[],
itemKey: string,
ref: MutableRefObject<HTMLInputElement> //<- here
//[...]
}
export const SmartInput: React.FC<SmartInputProps> = ({
items,
itemKey = 'name',
ref, //<- here
//[...]
}: SmartInputProps) => {
// [...]
// (lots of funcionality)
return (
<div>
<input ref={ref} /*<- here*/ /*[...]*/ />
//some more visual stuff, like displaying list of results
</div>
);
}
We add the ref to the custom component props and pass it to the ref
attribute of the vanilla html input field inside our custom component.
No we can query the field state from the root ref object.
e.g. let fieldValue = inputRef.current.value
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论