关于React项目中动画不生效的一些思考

我最近作的React项目中须要作这样的一个组件来展现数据。 css

image.png
根据不一样的数值,这个蓝色的条显示的宽度不一样。

这个其实很简单,用正常的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}
复制代码

而后打开浏览器看结果,果真成功了。 效果以下。

7月-19-2018 18-05-36.gif
相关文章
相关标签/搜索