1

恕我直言,来自React Hooks FAQ #getDerivedStateFromProps的建议 导致第一次渲染的值与 的值row不对应isScrollingDown。由于调用setIsScrollingDown只安排新的渲染并且不影响当前渲染,后者将使用新值row和旧值执行isScrollingDown

此行为不等同于getderivedstatefromprops允许row和之间的连贯性的组件类的静态方法isScrollingDown

为了保证连贯的渲染,不应该使用以下代码更新示例吗?还是我错过了什么?

谢谢 !

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}`;
}

4

1 回答 1

0

这是文档中的重要部分,使您的更改变得不必要:

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

于 2019-03-08T17:58:15.403 回答