我正在开发一个ReactJS应用程序。我有一个生成 HTML 表的组件。使用 Map 子组件为表生成行。每行包含一定数量的输入字段。
编辑输入字段时,在某些情况下,会在父组件中触发模态窗口。模式为用户提供了三个按钮的点击选择。单击模式中的特定按钮时,我希望焦点返回到用户正在编辑的输入字段。
谁能给我一些关于如何实现这一目标的指示?
我研究了使用 refs 的问题,但我看到的所有示例都使用具有一个输入的组件来演示它。由于模态是从父组件触发的,所以我正在努力了解如何使用/从子组件获取 ref。
感谢任何帮助。
我希望焦点返回到用户正在编辑的输入字段。
您有多个输入字段,并且希望专注于某个输入。为了能够做到这一点,您需要多个参考文献 --12 个参考文献--.
-
像这样定义你的引用:
const inputRef = useRef([]);
-
您需要将输入节点分配给 ref 数组。如果您使用某种循环来生成输入字段,则可以这样做:
<input ref={el => inputRef.current[i] = el} />
-
现在,您需要一个变量来存储当前正在编辑的输入的索引。
-
最后,您可以使用此变量(其中包含上次编辑的输入字段的索引(来实现您想要的,如下所示:
inputRef.current[i].focus()
如果使用类组件:
-
在构造函数中定义一个数组:
this.myRefs = []
-
分配 HTML 节点,如下所示:
<input ref={el => this.myRefs[i] = el} />
-
此步骤不会更改。
-
现在,您可以像这样聚焦特定的输入元素:
this.myRefs[i].focus()
以@user9408899的答案为指导并阅读,我想出了以下解决方案(仅显示与解决方案直接相关的部分代码(。
父组件
- 实现了一个
inputRefToFocus
属性来存储我们 想要添加焦点。 - 实现
setInputRefToFocus(ref)
以在状态中分配上述属性,也将此和inputRefToFocus
传递给子组件。
export class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
...
// this is the ref for the input field to focus on
// when modal window appears, depending on button clicked,
// we want to focus on the field user was editing
inputRefToFocus: null
};
this.setInputRefToFocus = this.setInputRefToFocus.bind(this);
}
setInputRefToFocus(ref) {
this.setState({ inputRefToFocus: ref });
}
render() {
{ rows.map(elem => (
<PivotTableRow
setInputRefToFocus={this.setInputRefToFocus}
inputRefToFocus={this.state.inputRefToFocus}
/>
)) }
}
}
子组件
创建输入元素时,每个输入元素都会添加到 ref 数组中。
当输入聚焦时,我们在父组件的
inputRefToFocus
属性中设置其 ref。- 将焦点设置为
componentDidUpdate()
export class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
...
};
this.inputRef = [];
}
componentDidUpdate(prevProps) {
if (this.props !== prevProps) {
if (this.inputRef[this.props.inputRefToFocus] !== undefined) {
this.inputRef[this.props.inputRefToFocus].focus();
}
}
}
render() {
return (
// loop to generate input elements
<Input
ref={el => { this.inputRef[dummyvalue] = el; }
onChange={...}
onFocus={() => this.props.setInputRefToFocus(dummyvalue)}
/>
);
}
}
我觉得代码可以显着改进,因为这是我第一次尝试它