React,如何从同一组件访问我的渲染函数中的 DOM 元素
React, how to access the DOM element in my render function from the same component
我想知道从同一组件访问渲染函数内的 DOM 元素的最佳做法是什么。请注意,我将在页面上多次呈现此组件。
例如
var TodoItem = React.createClass({
...
render:function(){
function oneSecLater(){
setTimeout(function(){
//select the current className? this doesn't work, but it gives you an idea what I want.
document.getElementsByClassName('name').style.backgroundColor = "red";
)}, 1000);
}
return(
<div className='name'>{this.oneSecLater}</div>
)
})
您可以使用 ref callback
访问 React 中的 dom 元素,这是 React Docs 推荐遵循的
并在 componentDidMount
生命周期函数中执行此操作,因为在创建 DOM 之前无法访问引用
var TodoItem = React.createClass({
...
componentDidMount() {
setTimeout(function(){
this.myDiv.style.backgroundColor = "red";
)}, 1000);
}
render:function(){
return(
<div className='name' ref={(ele) => this.myDiv = ele}></div>
)
})
您可以使用 ReactDOM.findDOMNode(this)
访问基础 DOM 节点。但是访问 DOM 节点并像您一样进行操作是违反 React 编程风格的。最好使用状态变量并调用 setState
方法来 re-render DOM.
这里不用setTimeout。组件有生命周期方法,其中 componentDidMount
在渲染后调用。因此,您可以在方法中获取对 div 的引用。
var TodoItem = React.createClass({
...
componentDidMount: function () {
if(this.myDiv) {
this.myDiv.style.backgroundColor = "red";
}
}
render:function(){
return(
<div className='name' ref = {c => this.myDiv = c}></div>
);
});
这是我的解决方案:
要获取特定元素的 computedCss,您需要先向 elemenet 添加 ref 属性。
enter image description here
render(){
<div>
<Row className="chartline2">
<Col className="gutter-row" span={24}>
<div className="gutter-box lineChartWrap" id="lineChartWrap" ref="lineChartWrap">
<LineChart data={lineChartData} options={lineChartOptions} width="100%" height="300"/>
</div>
</Col>
</Row>
</div>
}
然后,在 componentDidUpdate() 函数中,使用 window.getComputedStyle(this.refs.lineChartWrap).XXX 获取元素的 css
enter image description here
componentDidUpdate(){
console.log("------- get width ---");
let ele = document.querySelector("#lineCharWrap");
console.log(this.refs.lineChartWrap);
console.log(window.getComputedStyle(this.refs.lineChartWrap).width);
}
您应该避免访问 DOM 元素,因为 React 的全部意义在于对 dom 进行抽象。 React 在内存中保留 DOM 的表示形式,称为 VirtualDom。使用 VirtualDom 将使您的应用程序进行单元测试 easier.If 您真的知道自己在做什么,这里是如何做的:
componentDidMount(){
const name=this.name.current.style() //current will return the actual DOM
element
}
name=React.createRef() //create a ref object
<div ref={this.name} className="anything" /> //your classname does not need to be named as "name". You access the element via the "ref" attribute not the classname.
在 ComponentDidMount 中,当您的组件被安装时,它的样式更改将被应用。
在使用 React 14 打开条带结帐模式之前尝试进行表单验证后才遇到这个问题。
我想指出,您实际上并不是在访问带有引用的 DOM 元素。您只是在访问 React 组件对象。此处显示:
最上面的正在调用ref.ticketForm
,最下面的正在显示document.getElementById('ticketform')
。
我需要这样做的原因如下:
<Button color="success" size="lg" type="button" onClick={(e) => {
const ticketForm = document.getElementById('ticketForm');
const isValid = ticketForm.reportValidity();
if (!isValid) e.stopPropagation();
}}>Buy Tickets</Button>
reportValidity()
是一个DOM元素方法:https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reportValidity
参考这个问题,这个人展示了这个方法是在一个参考对象上使用的,这自然是不正确的:https://github.com/azmenak/react-stripe-checkout/issues/121#issuecomment-431635855
希望这能澄清 DOM 元素并不明确等于 React 组件。如果您需要以任何方式操纵 DOM ,请先以反应方式进行。这是一个边缘案例,我宁愿依赖动态表单的表单验证,也不愿手动执行非常繁重的自定义验证。
我想知道从同一组件访问渲染函数内的 DOM 元素的最佳做法是什么。请注意,我将在页面上多次呈现此组件。
例如
var TodoItem = React.createClass({
...
render:function(){
function oneSecLater(){
setTimeout(function(){
//select the current className? this doesn't work, but it gives you an idea what I want.
document.getElementsByClassName('name').style.backgroundColor = "red";
)}, 1000);
}
return(
<div className='name'>{this.oneSecLater}</div>
)
})
您可以使用 ref callback
访问 React 中的 dom 元素,这是 React Docs 推荐遵循的
并在 componentDidMount
生命周期函数中执行此操作,因为在创建 DOM 之前无法访问引用
var TodoItem = React.createClass({
...
componentDidMount() {
setTimeout(function(){
this.myDiv.style.backgroundColor = "red";
)}, 1000);
}
render:function(){
return(
<div className='name' ref={(ele) => this.myDiv = ele}></div>
)
})
您可以使用 ReactDOM.findDOMNode(this)
访问基础 DOM 节点。但是访问 DOM 节点并像您一样进行操作是违反 React 编程风格的。最好使用状态变量并调用 setState
方法来 re-render DOM.
这里不用setTimeout。组件有生命周期方法,其中 componentDidMount
在渲染后调用。因此,您可以在方法中获取对 div 的引用。
var TodoItem = React.createClass({
...
componentDidMount: function () {
if(this.myDiv) {
this.myDiv.style.backgroundColor = "red";
}
}
render:function(){
return(
<div className='name' ref = {c => this.myDiv = c}></div>
);
});
这是我的解决方案: 要获取特定元素的 computedCss,您需要先向 elemenet 添加 ref 属性。
enter image description here
render(){
<div>
<Row className="chartline2">
<Col className="gutter-row" span={24}>
<div className="gutter-box lineChartWrap" id="lineChartWrap" ref="lineChartWrap">
<LineChart data={lineChartData} options={lineChartOptions} width="100%" height="300"/>
</div>
</Col>
</Row>
</div>
}
然后,在 componentDidUpdate() 函数中,使用 window.getComputedStyle(this.refs.lineChartWrap).XXX 获取元素的 css enter image description here
componentDidUpdate(){
console.log("------- get width ---");
let ele = document.querySelector("#lineCharWrap");
console.log(this.refs.lineChartWrap);
console.log(window.getComputedStyle(this.refs.lineChartWrap).width);
}
您应该避免访问 DOM 元素,因为 React 的全部意义在于对 dom 进行抽象。 React 在内存中保留 DOM 的表示形式,称为 VirtualDom。使用 VirtualDom 将使您的应用程序进行单元测试 easier.If 您真的知道自己在做什么,这里是如何做的:
componentDidMount(){
const name=this.name.current.style() //current will return the actual DOM
element
}
name=React.createRef() //create a ref object
<div ref={this.name} className="anything" /> //your classname does not need to be named as "name". You access the element via the "ref" attribute not the classname.
在 ComponentDidMount 中,当您的组件被安装时,它的样式更改将被应用。
在使用 React 14 打开条带结帐模式之前尝试进行表单验证后才遇到这个问题。
我想指出,您实际上并不是在访问带有引用的 DOM 元素。您只是在访问 React 组件对象。此处显示:
最上面的正在调用ref.ticketForm
,最下面的正在显示document.getElementById('ticketform')
。
我需要这样做的原因如下:
<Button color="success" size="lg" type="button" onClick={(e) => {
const ticketForm = document.getElementById('ticketForm');
const isValid = ticketForm.reportValidity();
if (!isValid) e.stopPropagation();
}}>Buy Tickets</Button>
reportValidity()
是一个DOM元素方法:https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reportValidity
参考这个问题,这个人展示了这个方法是在一个参考对象上使用的,这自然是不正确的:https://github.com/azmenak/react-stripe-checkout/issues/121#issuecomment-431635855
希望这能澄清 DOM 元素并不明确等于 React 组件。如果您需要以任何方式操纵 DOM ,请先以反应方式进行。这是一个边缘案例,我宁愿依赖动态表单的表单验证,也不愿手动执行非常繁重的自定义验证。