提问者:小点点

通过更新响应CSS过渡不一致


下面的代码段有四个框。这样做的目的是,这些框的顺序将被洗牌,并在它们移动到新位置时发生过渡动画。每个框的键对应于useState中源数组的颜色值。每次通过shuffle按钮更新时,源数组的值都会被洗牌。然后在返回函数中映射数组。我为每个框设置了2个类名。一个类名与索引相对应,用于定位。另一个类名与源数组值对应,并且始终与该框的键一致。

我的问题是,反应似乎是随机决定要注意和调和的键,以及要忽略和重新加载这些元素的键。您可以在这里看到,一些元素正确地过渡,而另一些元素只是跳转到它们的目标位置。我不知道为什么会发生这种情况。有人能帮忙吗?

编辑:我不认为这是一个关于不必要的重新安装的协调问题。React正确使用钥匙,不重新安装任何钥匙。因此,问题在于React如何处理更新期间添加的CSS转换类。有些过渡工作,有些则不行。这可能只是引擎的一个限制,但如果有人有任何进一步的煽动请分享。

const {useState} = React;

function App() {
  const [state, setState] = useState(['Red', 'Green', 'Blue', 'Black'])

  function handleShuffle() {
    const newState = _.shuffle(state)
    setState(newState)
  }

  return ( 
    <div className="App"> 
      {state.map((sourceValue, index) => {
        return ( 
          <div className={
            'box positionAt' + index + ' sourceValue' + sourceValue
          }
          key={sourceValue} ></div>
        )
      })}

      <button id="shuffle" onClick={handleShuffle}> shuffle < /button> 
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render( <
  App / > ,
  rootElement
);
.App {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: gray;
}

.box {
  width: 25px;
  height: 25px;
  position: absolute;
  transition: transform 1s;
}

.positionAt0 {
  transform: translate(0px, 0px);
}

.positionAt1 {
  transform: translate(175px, 0px);
}

.positionAt2 {
  transform: translate(0px, 175px);
}

.positionAt3 {
  transform: translate(175px, 175px);
}

.sourceValueGreen {
  background-color: green;
}

.sourceValueBlue {
  background-color: blue;
}

.sourceValueRed {
  background-color: red;
}

.sourceValueBlack {
  background-color: black;
}

#shuffle {
  position: absolute;
  top: 0px;
  left: 75px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<div id="root"></div>

共1个答案

匿名用户

我花了一段时间才弄明白,因为为盒子设置正确的钥匙似乎是正确的。

我通过检查一个框并将其存储在一个变量中(b=$0),洗牌,用相同的键重新检查该框(颜色),并将其与存储的节点进行比较($0===b),验证了键的有效性。因此每个键的DOM节点都是稳定的。

但是对于CSS转换来说,这是不够的,因为浏览器改变DOM中元素顺序的方式。

您可以在一个最小化的示例中看到它,该示例可以有效地对DOM中的元素进行重新排序(我假设React在必须对元素进行重新排序时在内部执行类似的操作):

function reorder() {
    const list = document.querySelector("ul");
    list.appendChild(list.firstElementChild);
}
 <ul>
    <li>List-item #1</li>
    <li>List-item #2</li>
</ul>
<button onclick="reorder()">reorder!</button>