我使用ReactJS拥有无限深层树结构。我的树由具有以下模型的节点组成:
C
我正在尝试使用refs将焦点设置为其中一个子元素内的输入(请参阅https://reactjs.org/docs/refs-and-the-dom.html)。我确定要关注哪个节点使用其id。
我的节点组件是:
B
然后从父组件我可以在整个树上触发setFocus(id)方法(也使用refs)。
这是正确的方法还是有更简单/更有效的方法?这种方式产生的结果不一致。特别是一旦我改变树结构(即添加一个新节点)。
答案 0 :(得分:1)
您可以在componentDidMount方法中将ids
和focusCallback
注册到您的父组件。
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Node extends Component {
constructor(props) {
super(props);
this.setFocus = this.setFocus.bind(this);
}
static propTypes = {
registerNode: PropTypes.func,
}
componentDidMount() {
this.props.registerNode(this.props.node.id, () => {
this.inputWidget.focus();
});
}
render() {
const { node, registerNode } = this.props
const children = node.children
return (
<div>
<input type="text" ref={(input)=>{this.inputWidget = input}}
{children.map((n) =>
<Node registerNode={registerNode} key={n.id} node={n} />
</div>
)
}
}
export default Node
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
您的父组件应为您的子节点提供registerNode
方法:
class Head extends Component {
nodes = {};
registerNode = (id, focusCallback) => {
this.nodes[id] = callback;
};
render() {
const { tree } = this.props;
return tree.map(node =>
<Node registerNode={this.registerNode} key={node.id} node={node} />);
}
}
&#13;
现在,您可以使用this.nodes[id]();
现在我们还没有进行树遍历,因为我们只使用带有ID的map。所以我们提高运行速度
我们还删除了refs
组件上的额外Node
。