[英]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"];
我有一个名为ListContainerDIV
的styled-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发现了关于这个主题的这些推文:
关于计算虚拟dom,它首先渲染父组件,然后渲染子组件,然后渲染子组件,依此类推。 所有这些都使用状态和道具的最新值,因此App和各种子组件都知道列表更长。 这个虚拟dom只是一个内存中描述你想要的页面的样子。
一旦计算出虚拟dom,react会将之前的虚拟dom与新的dom进行比较,并找到已更改的内容。 在这种情况下,它发现需要将一个新样式添加到div中,并且需要将一些新的li插入到ul中。 这些应用的确切顺序是一个实现细节,但它们是同步应用的,浏览器不能在两者之间绘制,因此它可能同时进行。
传递给useState的参数,在这种情况下为shortList,是初始状态。 所以当ListContainerDIV第一次渲染时,它基于列表长度为3,所以idealHeight = 70
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.