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>");
我不认为getDOMNode
或findDOMNode
是我正在尝试做的事情的正确方法。
问题:是否可以在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'));
答案 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>
)
}