簡體   English   中英

React Hooks常見問題解答:getpropivedstatefromprops的實現導致呈現不連貫狀態

[英]React Hooks FAQ: implementation of getderivedstatefromprops leads to rendering with incoherent state

恕我直言,來自React Hooks常見問題解答#getDerivedStateFromProps的建議導致一個第一個渲染,該渲染的row值與isScrollingDown的值不對應。 由於對setIsScrollingDown的調用僅計划新渲染,並且不影響當前渲染,因此將使用row的新值和舊值isScrollingDown執行當前渲染。

此行為與組件類的靜態getderivedstatefromprops方法等效,該方法允許rowisScrollingDown之間保持一致。

為了保證連貫的渲染,示例是否不應該使用以下代碼進行更新? 還是我錯過了什么?

謝謝 !

 function ScrollView({row}) { let [isScrollingDown, setIsScrollingDown] = useState(false); let [prevRow, setPrevRow] = useState(null); if (row !== prevRow) { // Row changed since last render. Update isScrollingDown. isScrollingDown = prevRow !== null && row > prevRow setIsScrollingDown(isScrollingDown); setPrevRow(row); } return `Scrolling down: ${isScrollingDown}`; } 

這是文檔中的重要部分,使您無需進行更改:

退出第一個渲染后,React將立即以更新后的狀態重新運行組件,因此它並不昂貴。

它們不同步的渲染將永遠不會提交給瀏覽器。 實際上,如果它正在從渲染器返回子組件,則直到狀態更新后才執行子組件的渲染(從已渲染狀態的渲染器返回的子組件將被忽略)。

以下是添加了控制台日志以顯示此內容的示例。 請注意,當您增加行數時,ScrollView呈現兩次,但ScrollingDown僅呈現一次,僅接收到ScrollView狀態的最新版本。

import React, { useState } from "react";
import ReactDOM from "react-dom";

function ScrollingDown({ isScrollingDown, prevRow, row }) {
  console.log("ScrollingDown", isScrollingDown, prevRow, row);
  return (
    <div>
      {`Scrolling down: ${isScrollingDown}`}
      <br />
      {`prevRow: ${prevRow}`}
      <br />
      {`row: ${row}`}
    </div>
  );
}

function ScrollView({ row }) {
  let [isScrollingDown, setIsScrollingDown] = useState(false);
  let [prevRow, setPrevRow] = useState(null);

  if (row !== prevRow) {
    // Row changed since last render. Update isScrollingDown.
    setIsScrollingDown(prevRow !== null && row > prevRow);
    setPrevRow(row);
  }
  console.log("ScrollView", isScrollingDown, prevRow, row);
  return (
    <ScrollingDown
      isScrollingDown={isScrollingDown}
      prevRow={prevRow}
      row={row}
    />
  );
}

function App() {
  const [row, setRow] = useState(1);
  return (
    <div className="App">
      <ScrollView row={row} />
      <button onClick={() => setRow(prev => prev + 1)}>Increment Row</button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

編輯掛鈎getDerivedStateFromProps

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM