我最近作的React項目中須要作這樣的一個組件來展現數據。 css
這個其實很簡單,用正常的react的編程思惟,我只要根據數據動態的計算它的寬度,循環生成相應的節點就好了。 其中的部分核心react代碼以下react
{data && data.length > 0
? data.map((item, index) => (
<div className={styles.item} key={index}>
<div className={styles.itemTop}>
<span>{item.label}</span>
<span className={styles.num}>{item.value}</span>
</div>
<p className={styles.progressBar}>
<span
className={styles.inner}
style={{ background, width: getWidth(item.value)}
/>
</p>
</div>
))
: null}
複製代碼
這樣就實現如上圖所示的功能顯示,可是如今又有個需求,就是須要那個藍色的條剛加載出來的時候動起來。編程
transition瀏覽器
首當其衝的固然是css的transition屬性,而後把它加入代碼中bash
.inner {
width: 0;
transition: width 0.6s ease;
}
複製代碼
想象之中,一切都是這麼簡單, 但是這個動畫並無生效。dom
而後我就回過頭來思考它 爲何沒有生效?函數
transition這個屬性只有在width屬性發生改變的時候纔會產生做用。如今只能說明span的width並無發生改變。 這時候就要說到個人這段代碼了,它是一邊計算寬度,一邊渲染節點的,也就是說它節點生成的時候,寬度就已經定好了。因此transition固然不會生效了動畫
如今我要怎麼改進這段代碼使動畫生效呢?spa
我只能先讓節點生成好,而後再改變它的寬度了。3d
這就想到了react中的ref屬性了,這個屬性接受字符串或者一個函數,而這個函數在節點加載完成後或者節點銷燬時都會觸發。等span節點渲染完成後,我就能夠經過這個函數返回的真實的dom節點,操做它改變寬度了,這正是我所須要的。
有了思路,開始改進代碼。
{data && data.length > 0
? data.map((item, index) => (
<div className={styles.item} key={index}>
<div className={styles.itemTop}>
<span>{item.label}</span>
<span className={styles.num}>{item.value}</span>
</div>
<p className={styles.progressBar}>
<span
className={styles.inner}
style={{ background }}
ref={n => {
if (n && n.style) {
n.style.width = `${getWidth(item.value)}px`;
}
}}
/>
</p>
</div>
))
: null}
複製代碼
而後打開瀏覽器看結果,果真成功了。 效果以下。