我正在使用React Hooks-重写表单以使用钩子概念。一切正常,除了一旦我在输入中键入任何1个字符,输入就会失去焦点。
我猜有一个问题,即组件的外部不知道组件的内部更改,但是我该如何解决此问题?
这是useForm挂钩:
div {
margin: 80px;
}
div p {
font-size: 70px;
margin: 0;
display: inline;
background: orange;
padding: 50px;
}
以下是使用挂钩的组件:
import React, { useState } from "react";
export default function useForm(defaultState, label) {
const [state, setState] = useState(defaultState);
const FormComponent = () => (
<form>
<label htmlFor={label}>
{label}
<input
type="text"
id={label}
value={state}
placeholder={label}
onChange={e => setState(e.target.value)}
/>
</label>
</form>
);
return [state, FormComponent, setState];
}
答案 0 :(得分:8)
尽管Kais的答案可以解决症状,但仍无法解决原因。如果有多个输入,它也会失败-那么,哪个应该自动专注于重新渲染呢?
当您在另一个函数的范围内定义一个组件(FormComponent
)时,就会发生此问题,该函数称为App
组件的每个渲染。每次重新渲染FormComponent
组件并调用App
时,这都会为您提供一个全新的useState
。那么,这个新组成部分就没有重点了。
我个人感觉还是从挂钩中返回了组件。我将改为定义一个FormComponent
组件,并且仅从useForm状态返回状态。
但是,最接近原始代码的工作示例可能是:
// useForm.js
import React, { useState } from "react";
// Define the FormComponent outside of your useForm hook
const FormComponent = ({ setState, state, label }) => (
<form>
<label htmlFor={label}>
{label}
<input
type="text"
id={label}
value={state}
placeholder={label}
onChange={e => setState(e.target.value)}
/>
</label>
</form>
);
export default function useForm(defaultState, label) {
const [state, setState] = useState(defaultState);
return [
state,
<FormComponent state={state} setState={setState} label={label} />,
setState
];
}
// App.js
import useForm from "./useForm";
export default function App() {
const [formValue, Form] = useForm("San Francisco, CA", "Location");
return (
<>
<h1>{formValue}</h1>
{Form}
</>
);
}
答案 1 :(得分:4)
在输入框中输入任何文本时。父组件也在重新渲染。因此,您需要手动关注输入。
为此,请在输入标签中使用autoFocus
<input
type="text"
id={label}
value={state}
placeholder={label}
onChange={e => setState(e.target.value)}
autoFocus
/>
答案 2 :(得分:0)
第一个解决方案实际上对我有用,最初包含文本字段的功能组件是主要功能组件的一部分,我面临着同样的问题,但是当我将文本字段组件提取到另一个页面并将其导入时工作正常 这是我的组成部分
<Paper >
<div>
<div style={{padding:'10px' ,display:'flex'}} >
<inputstyle={{marginRight:'5px'}} value={val} onChange={(e)=>{setVal(e.target.value)}} />
</div>
</div>
</Paper>
答案 3 :(得分:0)
以上答案对我不起作用。对我有用的解决方案要简单得多,因此也不那么明显。
问题
本质上,我随输入更改的值也用于输入列表中的每个 key
。
因此,当我更新值时,key
会改变,React 会检测到它与最后一个键不同,并在其位置创建一个新输入。作为一个新的输入,它不会专注于自己。
但是,通过使用 autoFocus
,它会自动关注新创建的输入。但问题并没有得到解决,因为很明显,输入不断地经历着一个不聚焦和聚焦的循环。
这是一个article demonstrating问题。
修复
将 key
更新为不可更改的值,以便 React 可以稳定引用列表项。就我而言,我只是将其更新为索引。这并不理想(React docs 建议使用稳定的 ID),但在我的情况下还可以,因为项目的顺序不会改变。