Javascript 如何在 React 中附加到 dom?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30721836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:39:08  来源:igfitidea点击:

How to append to dom in React?

javascriptreactjs

提问by BrainLikeADullPencil

Here's a js fiddleshowing the question in action.

这是一个显示问题的 js 小提琴

In the render function of a component, I render a div with a class .blah. In the componentDidMountfunction of the same component, I was expecting to be able to select the class .blahand append to it like this (since the component had mounted)

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

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

However, the appended content does not show up. I also tried (shown also in the fiddle) to append in the same way but from a parent component into a subcomponent, with the same result, and also from the subcomponent into the space of the parent component with the same result. My logic for attempting the latter was that one could be more sure that the dom element had been rendered.

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

At the same time, I was able (in the componentDidMountfunction) to getDOMNodeand append to that

同时,我能够(在componentDidMount函数中)getDOMNode附加到那个

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

yet reasons to do with CSS styling I wished to be able to append to a div with a class that I know. Also, since according to the docsgetDOMNodeis deprecated, and it's not possible to use the replacement to getDOMNodeto do the same thing

然而,使用 CSS 样式的原因我希望能够使用我知道的类附加到 div。此外,由于根据文档getDOMNode已弃用,并且不可能使用替换getDOMNode来做同样的事情

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

I don't think getDOMNodeor findDOMNodeis the correct way to do what I'm trying to do.

我不认为getDOMNode或者findDOMNode是做我想做的事情的正确方法。

Question:Is it possible to append to a specific id or class in React? What approach should I use to accomplish what I'm trying to do (getDOMNodeeven though it's deprecated?)

问题:是否可以在 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'));

采纳答案by Felix Kling

In JSX, you have to use className, not class. The console should show a warning about this.

在 JSX 中,您必须使用className,而不是class. 控制台应显示有关此警告。

Fixed example: https://jsfiddle.net/69z2wepo/9974/

固定示例:https: //jsfiddle.net/69z2wepo/9974/

You are using React.findDOMNodeincorrectly. You have to pass a React component to it, e.g.

您使用React.findDOMNode不当。你必须向它传递一个 React 组件,例如

var node = React.findDOMNode(this);

would return the DOM node of the component itself.

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

However, as already mentioned, you really should avoid mutating the DOM outside React. The whole point is to describe the UI oncebased on the state and the props of the component. Then change the state or props to rerender the component.

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

回答by agmcleod

Avoid using jQuery inside react, as it becomes a bit of an antipattern. I do use it a bit myself, but only for lookups/reads that are too complicated or near impossible with just react components.

避免在 react 中使用 jQuery,因为它有点反模式。我自己确实使用过它,但仅用于太复杂或几乎不可能仅使用反应组件的查找/读取。

Anyways, to solve your problem, can just leverage a state object:

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

<!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>

Sorry for JSX conversion, but was just easier for me to test without setting up grunt :).

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

Anyways, what i'm doing is leveraging the state property. When you call setState, render() is invoked again. I then leverage props to pass data down to the sub component.

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

回答by Sean Redmond

Here's a version of your JSFiddle with the fewest changes I could make: JSFiddle

这是你的 JSFiddle 的一个版本,我可以做的改动最少:JSFiddle

agmcleod's advice is right -- avoid JQuery. I would add, avoid JQuery thinking, which took me a while to figure out. In React, the render method should render what you want to see based on the state of the component. Don't manipulate the DOM after the fact, manipulate the state. When you change the state, the component will be re-rendered and you'll see the change.

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

Set the initial state (we haven't appended anything).

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

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

Change the state (we want to append)

更改状态(我们要追加)

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

Now the render function can show the extra text or not based on the state:

现在渲染函数可以根据状态显示或不显示额外的文本:

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>
    )
}