如何在React中附加到dom?

时间:2015-06-09 01:54:47

标签: javascript reactjs

Here's a js fiddle显示了问题的实际效果。

在组件的渲染功能中,我使用类.blah渲染div。在同一组件的componentDidMount函数中,我期望能够选择类.blah并像这样附加到它(因为组件已经安装)

$('.blah').append("<h2>Appended to Blah</h2>");

但是,附加的内容不会显示。我也试过(也在小提琴中显示)以相同的方式追加但是从父组件追加到具有相同结果的子组件,并且还从子组件追加到具有相同结果的父组件的空间中。我尝试后者的逻辑是,人们可以更加确定dom元素已被渲染。

与此同时,我能够(在componentDidMount函数中)getDOMNode并追加到

 var domnode = this.getDOMNode(); 
 $(domnode).append("<h2>Yeah!</h2>")

还有CSS样式的理由我希望能够附加一个我知道的类的div。此外,由于docs getDOMNode已弃用,并且无法使用替换getDOMNode来执行相同的操作

 var reactfindDomNode = React.findDOMNode();
 $(reactfindDomNode).append("<h2>doesn't work :(</h2>");

我不认为getDOMNodefindDOMNode是我正在尝试做的事情的正确方法。

问题:是否可以在React中附加到特定的ID或类?我应该采用什么方法来完成我尝试做的事情(getDOMNode,即使它被弃用了?)

var Hello = React.createClass({
    componentDidMount: function(){

       $('.blah').append("<h2>Appended to Blah</h2>");
       $('.pokey').append("<h2>Can I append into sub component?</h2>");
       var domnode = this.getDOMNode();
       $(domnode).append("<h2>appended to domnode but it's actually deprecated so what do I use instead?</h2>")

       var reactfindDomNode = React.findDOMNode();
       $(reactfindDomNode).append("<h2>can't append to reactfindDomNode</h2>");

    },
    render: function() {
        return (
            <div class='blah'>Hi, why is the h2 not being appended here?
            <SubComponent/>
            </div>
        )
    }
});

var SubComponent = React.createClass({

      componentDidMount: function(){
         $('.blah').append("<h2>append to div in parent?</h2>");
      },

      render: function(){
         return(
              <div class='pokey'> Hi from Pokey, the h2 from Parent component is not appended here either?            
              </div>
         )
      }
})

React.render(<Hello name="World" />, document.getElementById('container'));

3 个答案:

答案 0 :(得分:8)

在JSX中,您必须使用className,而不是class。控制台应该显示一个警告。

修复示例:https://jsfiddle.net/69z2wepo/9974/

您错误地使用了React.findDOMNode。您必须将React组件传递给它,例如

var node = React.findDOMNode(this);

将返回组件本身的DOM节点。

但是,正如已经提到的,你真的应该避免在React之外改变DOM。重点是根据组件的状态和道具描述UI 一次。然后更改状态或道具以重新渲染组件。

答案 1 :(得分:3)

避免在内部使用jQuery,因为它变得有点像反模式。我自己稍微使用它,但仅用于查找/读取太复杂或几乎不可能的反应组件。

无论如何,要解决您的问题,只需利用状态对象:

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script src="https://fb.me/react-0.13.3.js"></script>

  </head>
  <body>
    <div id='container'></div>
    <script>
    'use strict';

var Hello = React.createClass({
    displayName: 'Hello',

    componentDidMount: function componentDidMount() {
        this.setState({
            blah: ['Append to blah'],
            pokey: ['pokey from parent']
        });
    },

    getInitialState: function () {
      return {
        blah: [],
        pokey: []
      };
    },

    appendBlah: function appendBlah(blah) {
        var blahs = this.state.blah;
        blahs.push(blah);
        this.setState({ blah: blahs });
    },
    render: function render() {
        var blahs = this.state.blah.map(function (b) {
            return '<h2>' + b + '</h2>';
        }).join('');
        return React.createElement(
            'div',
            { 'class': 'blah' },
            { blahs: blahs },
            React.createElement(SubComponent, { pokeys: this.state.pokey, parent: this })
        );
    }
});

var SubComponent = React.createClass({
    displayName: 'SubComponent',

    componentDidMount: function componentDidMount() {
        this.props.parent.appendBlah('append to div in parent?');
    },

    render: function render() {
        var pokeys = this.props.pokeys.map(function (p) {
            return '<h2>' + p + '</h2>';
        }).join('');
        return React.createElement(
            'div',
            { 'class': 'pokey' },
            { pokeys: pokeys }
        );
    }
});

React.render(React.createElement(Hello, { name: 'World' }), document.getElementById('container'));
    </script>
  </body>
</html>

很抱歉JSX转换,但我更容易测试而不设置grunt :)。

无论如何,我正在做的是利用国家财产。调用setState时,再次调用render()。然后我利用道具将数据传递给子组件。

答案 2 :(得分:2)

这是您的JSFiddle的一个版本,我可以做出最少的更改:JSFiddle

agmcleod的建议是正确的 - 避免使用JQuery。我想补充一点,避免JQuery思考,这花了我一段时间才弄明白。在React中,render方法应根据组件的状态呈现您想要查看的内容。事后,不要操纵DOM,操纵状态。当您更改状态时,组件将被重新渲染,您将看到更改。

设置初始状态(我们没有附加任何内容)。

getInitialState: function () {
    return {
        appended: false
    };
},

更改状态(我们要追加)

componentDidMount: function () {
    this.setState({
        appended: true
    });
    // ...
}

现在,渲染功能可以根据状态显示额外的文本:

render: function () {
    if (this.state.appended) {
        appendedH2 = <h2>Appended to Blah</h2>;
    } else {
        appendedH2 = "";
    }
    return (
        <div class='blah'>Hi, why isn't the h2 being appended here? {appendedH2}
        <SubComponent appended={true}/> </div>
    )
}