[英]React: Can't get correct width of element after render
如果一段文本大於其容器,我正在嘗試在 React 中設置一個選取框,但我無法獲得容器的正確寬度,即使在組件呈現之后也是如此。
我在另一個答案中讀到React “after render” 代碼? 您必須使用我正在嘗試的 requestAnimationFrame 但它仍然無法正常工作。
如果我記錄容器的寬度,它會顯示 147px 的寬度,這是在樣式表中使用 min-width 設置的,但正確的寬度應該是 320px,當屏幕 min-width 為 600px 時,它是使用媒體查詢設置的。
這是一個子組件,如果它有任何不同,父組件會在 iFrame 內呈現,並且 iFrame 的寬度遠遠超過 600px。
JS:
module.exports = React.createClass({
componentDidUpdate: function () {
// Setup marquee
this.initMarquee();
},
render: function () {
// Setup marquee
this.initMarquee();
var artistName = this.props.artist.artistName;
var trackName = this.props.track.trackName;
return (
<div className="MV-player-trackData no-select" ref="mvpTrackData">
<div className="MV-player-trackData-marquee-wrap" ref="mvpMarqueeWrap">
<div className="MV-player-trackData-marquee" ref="mvpMarquee">
<a className="MV-player-trackData-link no-select" href={this.props.storeUrl} target="_blank">
<span id="mvArtistName">{artistName}</span> – <span id="mvTrackName">{trackName}</span>
</a>
</div>
</div>
</div>
)
},
initMarquee: function () {
if ( typeof requestAnimationFrame !== 'undefined' ) {
//store a this ref, and
var self = this;
//wait for a paint to setup marquee
window.requestAnimationFrame(function() {
self.marquee();
});
}
else {
// Suport older browsers
window.setTimeout(this.marquee, 2000);
}
},
marquee: function () {
var marquee = React.findDOMNode(this.refs.mvpMarquee);
var marqueeWrap = React.findDOMNode(this.refs.mvpMarqueeWrap);
// If the marquee is greater than its container then animate it
if ( marquee.clientWidth > marqueeWrap.clientWidth ) {
marquee.className += ' is-animated';
}
else {
marquee.className = marquee.className.replace('is-animated', '');
}
}
});
CSS:
.MV-player-trackData-marquee-wrap {
height: 20px;
line-height: 20px;
min-width: 147px;
overflow: hidden;
position: relative;
width: 100%;
@media only screen and (min-width : 600px) {
min-width: 320px;
}
}
我嘗試了許多不同的解決方案,包括layout和react-component-width-mixin,但它們都不起作用。 我嘗試反應組件寬度混合,因為在我的應用程序的另一部分,我試圖獲取window.innerWidth
的值,但在渲染后也會返回 0,除非我設置了大約 2 秒的超時,但不幸的是有時 2 秒不是'由於數據加載和其他回調,時間足夠長,因此可以輕松剎車。
任何幫助都非常感謝。 謝謝。
更新:答案之一正確指出我應該調用this.initMarquee();
在我正在做的componentDidMount
內部,不幸的是我粘貼了錯誤的代碼,我在測試時粘貼了錯誤的代碼,以查看在render
調用它是否有所不同。 正確的代碼如下所示:
componentDidMount: function () {
// Setup marquee
this.initMarquee();
},
不幸的是,這也不起作用,我仍然收到不正確的 marqueeWrap 寬度。
更新:24/06/2015只是為了澄清,這是我想要實現的選取框效果,僅當文本大於其容器時,因為當它不是更大時滾動它是毫無意義的。
這里還有一個來自 React 團隊的Github 問題的鏈接,它談到了為什么 React 在瀏覽器繪制之前呈現。 - 在這種情況下,我想知道如何可靠地獲得相關元素的寬度。
可能發生的一個問題是,在componentDidMount觸發時,您的CSS尚未加載。 使用webpack可能會發生這種情況,並且即使您的項目中的組件之前已包含css,也將css包含在還包含js的包中。
正如您所指出的,在處理虛擬DOM時存在幾個問題。 您絕對不想嘗試使用jQuery來操縱DOM節點,而React可能會為您的嘗試大喊大叫。
有一個名為React-Context的庫,它將完全滿足您的要求。 您可以將其api公開給包裝器組件,然后能夠偵聽虛擬dom內組件上的事件。
這個庫有點塵土飛揚,但是它應該可以與您共享的代碼示例一起使用。
我對這個問題感到困惑,您要如何處理寬度?
此外,React只是JavaScript,因此您應該能夠在componentDidMount函數上觸發一些代碼,該函數在元素在瀏覽器dom中具有物理空間之后執行。 因此,就像任何JavaScript代碼一樣,您將能夠訪問該div並獲取其寬度等。
JavaScript方式...
document.getElementById("mydiv").offsetWidth;
jQuery方式...
$('#mydiv').width();
如果您要解決的問題是動態更改div的寬度,因為它在渲染后看起來不正確,等等...這實際上應該使用CSS來完成。
您不應該調用this.initMarquee();
在render()方法中。
通常,您根本不應該在render()
方法中使用DOM。
嘗試調用this.initMarquee();
在componentDidMount
方法中。
(在這種情況下,我真的不理解requestAnimationFrame
的用法)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.