Javascript React何时以及以什么顺序更新DOM?
我很难确定DOM更新的确切时间 注意:我在下面的示例中使用了Javascript React何时以及以什么顺序更新DOM?,javascript,reactjs,react-hooks,styled-components,Javascript,Reactjs,React Hooks,Styled Components,我很难确定DOM更新的确切时间 注意:我在下面的示例中使用了样式化组件 参见此示例: 代码沙盒: 它显示容器的max height属性的转换 它工作正常。我只是不知道它为什么会起作用 代码: 两份清单: 入围名单需要高度70px longList需要高度124px 我有一个名为ListContainerDIV的styled组件容器,它将基于props处理转换。道具名称为idealHeight const ListContainerDIV = styled.div` overflow:
样式化组件
参见此示例:
代码沙盒:
它显示容器的max height
属性的转换
它工作正常。我只是不知道它为什么会起作用
代码:
两份清单:
入围名单
需要高度70px
longList
需要高度124px
我有一个名为ListContainerDIV
的styled组件
容器,它将基于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>
);
}
函数应用程序(){
//状态为CONTAINER DIV元素保留列表和REF
const[list,setList]=useState(短名单);
const containerDiv_Ref=useRef(空);
//从单击按钮在列表之间切换的功能
函数变更列表(){
设置列表(prevState=>{
如果(prevState.length==3){
返回长列表;
}否则{
返回短名单;
}
});
}
//在渲染期间计算理想高度
设理想高度=null;
如果(list.length==3){
理想高度=70;
}else if(list.length==6){
理想高度=124;
}
//返回带有'idealHeight'属性的LISTCONTAINER
返回(
变化表
);
}
列出组件
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>
);
}
这是一个简单的组件,用于呈现
和的
function ListComponent(props) {
const listItems = props.list.map(item => <li key={item}>{item}</li>);
return <ul>{listItems}</ul>;
}
函数列表组件(道具){
const listItems=props.list.map(item=>{item} );
返回{listItems}
;
}
问题
如果在渲染列表之前设置组件的最大高度
,该转换如何工作?我的意思是,idealHeight
是在应用程序渲染期间设置的。我在想,longList
将在一个已经有max height=124
的容器中呈现?如果发生这种情况,我们就不会看到过渡,对吗
在这种情况下运行的事件顺序是什么
显然,在从样式化组件
容器更新div
之前,它先更新
和的
内部组件的元素总是在外部组件的元素之前更新
更新
刚刚发现Dan Abramov关于这个主题的推文:
传递给useState(本例中为短名单)的参数是初始状态。因此,当第一次呈现ListContainerDIV时,它基于列表长度为3,因此理想高度=70关于计算虚拟dom,它首先呈现父组件,然后呈现子组件,然后呈现子组件,依此类推。所有这些都使用状态和道具的最新值,因此应用程序和各种子组件都知道列表更长。这个虚拟dom只是对页面外观的内存描述
计算完虚拟dom后,react会将以前的虚拟dom与新的虚拟dom进行比较,并查找更改的内容。在本例中,它发现有一个新的样式需要添加到div中,一些新的li需要插入到ul中。这些应用的确切顺序是一个实现细节,但它们是同步应用的,浏览器无法在两者之间绘制,因此最好是同时绘制。如果我不清楚,很抱歉。我明白了。第二个渲染(当列表更新时)是我没有得到的。如果我在呈现ListComponent
之前就设置了max height
,那么转换如何工作呢?谢谢!是否确定DOM更新是同步的,并且浏览器仅在它们全部完成时才绘制?是的,react的提交阶段(我的第二段)保证是同步的。