繁体   English   中英

React何时以何种顺序更新DOM?

[英]When and in what order does React update the DOM?

我遇到了React更新DOM的确切时刻。

注意:我在下面的示例中使用styled-components

看这个例子:

CodeSandbox: https ://codesandbox.io/s/elegant-dirac-j6e54

它显示了容器的max-height属性的转换。

在此输入图像描述

它按预期工作。 我只是不知道为什么它有效。

代码:

两个清单:

  • shortList需要70px的高度
  • longList需要124px的高度
const shortList = ["Item 1", "Item 2", "Item 3"];
const longList = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"];

我有一个名为ListContainerDIVstyled-component容器,它将处理基于props的转换。 道具名称是idealHeight

const ListContainerDIV = styled.div`
  overflow: hidden;
  max-height: ${props => props.idealHeight + "px"};
  transition: max-height ease-out .5s;
`;

应用组件

function App() {

  // STATE TO KEEP LIST AND REF FOR THE CONTAINER DIV ELEMENT
  const [list, setList] = useState(shortList);
  const containerDiv_Ref = useRef(null);

  // FUNCTION TO TOGGLE BETWEEN LISTS FROM BUTTON CLICK
  function changeList() {
    setList(prevState => {
      if (prevState.length === 3) {
        return longList;
      } else {
        return shortList;
      }
    });
  }

  // CALCULATING THE IDEALHEIGHT DURING THE RENDER
  let idealHeight = null;

  if (list.length === 3) {
    idealHeight = 70;
  } else if (list.length === 6) {
    idealHeight = 124;
  }

  // RETURNING THE LISTCONTAINER WITH THE `idealHeight` PROP
  return (
    <React.Fragment>
      <button onClick={changeList}>Change List</button>
      <ListContainerDIV ref={containerDiv_Ref} idealHeight={idealHeight}>
        <ListComponent list={list} />
      </ListContainerDIV>
    </React.Fragment>
  );
}

列表组件

这是渲染<ul><li>'s的简单组件

function ListComponent(props) {
  const listItems = props.list.map(item => <li key={item}>{item}</li>);
  return <ul>{listItems}</ul>;
}

如果我在渲染列表之前设置组件的max-height ,那么这种转换如何工作呢? 我的意思是,在App渲染期间正在设置idealHeight 我以为longList将在一个已经有max-height = 124的容器中呈现? 如果发生这种情况,我们就不会看到过渡,对吗?

React在这种情况下运行的事件顺序是什么?

显然它在更新styled-component容器的div之前更新<ul><li>'s

内部组件的元素将始终在外部组件的元素之前更新?


UPDATE

刚刚从Dan Abramov发现了关于这个主题的这些推文:

https://twitter.com/dan_abramov/status/981869076166344704

在此输入图像描述 在此输入图像描述

关于计算虚拟dom,它首先渲染父组件,然后渲染子组件,然后渲染子组件,依此类推。 所有这些都使用状态和道具的最新值,因此App和各种子组件都知道列表更长。 这个虚拟dom只是一个内存中描述你想要的页面的样子。

一旦计算出虚拟dom,react会将之前的虚拟dom与新的dom进行比较,并找到已更改的内容。 在这种情况下,它发现需要将一个新样式添加到div中,并且需要将一些新的li插入到ul中。 这些应用的确切顺序是一个实现细节,但它们是同步应用的,浏览器不能在两者之间绘制,因此它可能同时进行。

传递给useState的参数,在这种情况下为shortList,是初始状态。 所以当ListContainerDIV第一次渲染时,它基于列表长度为3,所以idealHeight = 70

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM