如何自动聚焦 React 中的特定输入字段(单击另一个元素后)?
How to autofocus on a specific input field in React (after clicking on another element)?
我在 table 中有几个输入字段(每行都有一个输入字段),每个字段都动态命名,如下所示:
<table>
<tr>
<td>
<input
key={name}
type="text"
value={label}
name={name}
/>
<span>Edit</span>
</td>
</tr>
</table>
请注意,我在某个对象上进行映射以呈现包含输入字段的每个 <td />
。
我希望发生的情况是,当我单击该特定行的 "Edit" 时,同一行上的输入字段将获得焦点。
我从 React 文档中看到的是,如果您有一组预定义的输入字段并且您能够为每个字段执行 createRef()
,那么如何触发此焦点。
但是,如果您的输入字段是动态呈现的并且可能有 X 个(取决于被映射的对象),您将如何做到这一点?
您可以创建一个映射到 table 中每个项目的多个引用,如下例所示。
const rows = [
{ id: "a", name: "Panel 1" },
{ id: "b", name: "Panel 2" },
{ id: "c", name: "Panel 3" }
];
const refs = useRef(new Map()).current;
return (
<div>
<table>
{rows.map(row => (
<tr>
<td>
<input
label={row.name}
ref={inst =>
inst === null ? refs.delete(row.id) : refs.set(row.id, inst)
}
type="text"
/>
<span onClick={() => refs.get(row.id).focus()}>Edit</span>
</td>
</tr>
))}
</table>
</div>
这里是一个工作沙箱的 link。
为什么不在映射对象时动态创建 ref
?
{elements.map(() => {
const ref = React.createRef();
return <td>
<input
key={name}
type="text"
value={label}
name={name}
ref={ref}
/>
<span onClick={event => {
ref.current.focus()
}}>Edit</span>
</td>
})}
您可以创建一个空数组来存储您的 refs
。然后,当您 map
处理数据以创建输入时,通过 ref
属性和回调创建并推送 ref
。
查看工作沙箱:https://codesandbox.io/s/interesting-roentgen-q64jl
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const list = [{ name: "apple", label: "seed" }, { name: "you", label: "cat" }];
class App extends React.Component {
constructor(props) {
super(props);
this.refsArr = [];
}
focusIntoInput = index => {
this.refsArr[index].focus();
};
render() {
return (
<table>
<tr>
{list.map(({ name, label }, index) => {
return (
<td>
<input
ref={ref => this.refsArr.push(ref)}
key={name}
type="text"
value={label}
name={name}
/>
<span onClick={() => this.focusIntoInput(index)}>Edit</span>
</td>
);
})}
</tr>
</table>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
在 focusIntoInput
点击处理程序中,传递的 index
将始终对应于 refs
数组中的 ref
。
我在 table 中有几个输入字段(每行都有一个输入字段),每个字段都动态命名,如下所示:
<table>
<tr>
<td>
<input
key={name}
type="text"
value={label}
name={name}
/>
<span>Edit</span>
</td>
</tr>
</table>
请注意,我在某个对象上进行映射以呈现包含输入字段的每个 <td />
。
我希望发生的情况是,当我单击该特定行的 "Edit" 时,同一行上的输入字段将获得焦点。
我从 React 文档中看到的是,如果您有一组预定义的输入字段并且您能够为每个字段执行 createRef()
,那么如何触发此焦点。
但是,如果您的输入字段是动态呈现的并且可能有 X 个(取决于被映射的对象),您将如何做到这一点?
您可以创建一个映射到 table 中每个项目的多个引用,如下例所示。
const rows = [
{ id: "a", name: "Panel 1" },
{ id: "b", name: "Panel 2" },
{ id: "c", name: "Panel 3" }
];
const refs = useRef(new Map()).current;
return (
<div>
<table>
{rows.map(row => (
<tr>
<td>
<input
label={row.name}
ref={inst =>
inst === null ? refs.delete(row.id) : refs.set(row.id, inst)
}
type="text"
/>
<span onClick={() => refs.get(row.id).focus()}>Edit</span>
</td>
</tr>
))}
</table>
</div>
这里是一个工作沙箱的 link。
为什么不在映射对象时动态创建 ref
?
{elements.map(() => {
const ref = React.createRef();
return <td>
<input
key={name}
type="text"
value={label}
name={name}
ref={ref}
/>
<span onClick={event => {
ref.current.focus()
}}>Edit</span>
</td>
})}
您可以创建一个空数组来存储您的 refs
。然后,当您 map
处理数据以创建输入时,通过 ref
属性和回调创建并推送 ref
。
查看工作沙箱:https://codesandbox.io/s/interesting-roentgen-q64jl
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const list = [{ name: "apple", label: "seed" }, { name: "you", label: "cat" }];
class App extends React.Component {
constructor(props) {
super(props);
this.refsArr = [];
}
focusIntoInput = index => {
this.refsArr[index].focus();
};
render() {
return (
<table>
<tr>
{list.map(({ name, label }, index) => {
return (
<td>
<input
ref={ref => this.refsArr.push(ref)}
key={name}
type="text"
value={label}
name={name}
/>
<span onClick={() => this.focusIntoInput(index)}>Edit</span>
</td>
);
})}
</tr>
</table>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
在 focusIntoInput
点击处理程序中,传递的 index
将始终对应于 refs
数组中的 ref
。