ReactJS将焦点设置为树结构中的输入

时间:2018-02-17 12:35:16

标签: reactjs treeview

我使用ReactJS拥有无限深层树结构。我的树由具有以下模型的节点组成:

C

我正在尝试使用refs将焦点设置为其中一个子元素内的输入(请参阅https://reactjs.org/docs/refs-and-the-dom.html)。我确定要关注哪个节点使用其id。

我的节点组件是:

B

然后从父组件我可以在整个树上触发setFocus(id)方法(也使用refs)。

这是正确的方法还是有更简单/更有效的方法?这种方式产生的结果不一致。特别是一旦我改变树结构(即添加一个新节点)。

1 个答案:

答案 0 :(得分:1)

您可以在componentDidMount方法中将idsfocusCallback注册到您的父组件。



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;
&#13;
&#13;

您的父组件应为您的子节点提供registerNode方法:

&#13;
&#13;
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;
&#13;
&#13;

现在,您可以使用this.nodes[id]();

将焦点设置为任何输入

现在我们还没有进行树遍历,因为我们只使用带有ID的map。所以我们提高运行速度 我们还删除了refs组件上的额外Node