如何在React中添加dom

How to append to dom in React?

本文关键字:添加 dom React      更新时间:2023-09-26

下面的js演示了这个问题。

在组件的呈现函数中,我用类.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。此外,由于根据文档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'));

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

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

您使用React.findDOMNode错误。你必须传递一个React组件给它,例如

var node = React.findDOMNode(this);

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

然而,正如已经提到的,你真的应该避免在React外部改变DOM。重点是根据组件的状态和道具描述UI 一次。然后改变状态或道具来呈现组件。

避免在react中使用jQuery,因为它会变成一种反模式。我自己也用过一点,但只用于过于复杂或几乎不可能使用react组件的查找/读取。

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

<!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()会被再次调用。然后,我利用props将数据向下传递给子组件。

这是我可以做的最少更改的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>
    )
}