反应 - 访问DOM而不破坏封装

时间:2016-04-19 20:24:14

标签: javascript reactjs

在没有破坏封装的情况下,有没有一种方法可以做类似下面的事情?

import React, { Component, PropTypes } from 'react';

class Dashboard extends Component {
    constructor(props, context) {
        super(props, context);

        this.setRef = ::this.setRef;
    }
    componentDidMount() {
        const node = ReactDOM.findDOMNode(this.someRef);
        const newHeight = window.innerHeight - node.offsetTop - 30;
        node.style.maxHeight = `${newHeight}px`;
    }

    render() {
        return (
            <div id="some-element-id" ref={this.setRef}>
            </div>
        );
    }

    setRef(ref) {
        this.someRef= ref;
    }
}

ReactDOM.findDOMNode似乎是建议的解决方法,但这仍然打破了封装,文档在这个程度上有一个很大的红旗。

2 个答案:

答案 0 :(得分:2)

虽然这在技术上“破坏了封装”的一般意义上,如果没有其他方法可以做到(并且在这种情况下没有),那么使用findDOMNode是你唯一的选择,它是正确的。

如果您发现自己反复使用它,则应创建一个包装器组件来封装该行为。

答案 1 :(得分:2)

您应该使用组件“state”来设置react元素的style property,这样您只能访问“真实”DOM节点来计算高度,然后更新状态,重新渲染组件。现在,react组件具有与真实DOM节点相同的信息,因此它不应该破坏封装。

使用vanilla JS提供示例:

var Component = React.createClass({
    getInitialState: function(){
    return {
        style: {},
    }
  },
  componentDidMount: function(){
    var node = ReactDOM.findDOMNode(this);
    var newHeight = window.innerHeight - node.offsetTop - 30;
    this.setState({style: {backgroundColor: '#bbb', height: newHeight.toString() + 'px' }});
  },
  render: function(){
    return React.createElement('div', {style: this.state.style}, 'Height: ' + this.state.style.height);
  },
});

您可以在this fiddle中看到它正在运行。