这是我的代码沙箱示例: https://codesandbox.io/s/react-hooks-counter-demo-kevxp?file=/src/index.js
我的问题是: 该列表将始终在页面内的每个状态更改时重新呈现,因此滚动将始终返回顶部。我想知道为什么会这样,以及如何防止这种行为,即使列表的状态发生变化,然后保持列表的最后滚动位置
答案 0 :(得分:2)
每次渲染App
时,您都在为Example
组件创建一个全新的定义。它可能与旧的功能相同,但它是新的组件。因此react将一个渲染的元素与下一个渲染的元素进行比较,发现它们具有不同的组件类型。因此,就像您将某项从<div>
更改为<span>
一样,它被迫卸载旧的而安装新的。新的开始滚动到0。
解决方案是在App外部仅创建一次Example。
const Example = props => (
<List
className="List"
height={80}
itemCount={props.propsAbc.length}
itemSize={20}
width={300}
itemData={{
dataAbc: props.propsAbc
}}
>
{({ index, style, data }) => (
<div className={index % 2 ? "ListItemOdd" : "ListItemEven"} style={style}>
{data.dataAbc[index]}
</div>
)}
</List>
);
function App() {
const [count, setCount] = useState(0);
let [dataArray, setDataArray] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
return (
<div className="App">
<h1>Scroll down the blue box, then click the button</h1>
<h2>You clicked {count} times!</h2>
<button onClick={() => setCount(count - 1)}>Decrement</button>
<button onClick={() => setCount(count + 1)}>Increment</button>
<div
style={{ maxHeight: "80px", overflow: "äuto", background: "lightblue" }}
>
<Example propsAbc={dataArray} />
</div>
</div>
);
}
答案 1 :(得分:1)
我不认为这是反应窗口问题。
反应组件重新呈现,因为状态发生了变化。在这种情况下,状态更改是由setCount(单击增加按钮时)引起的,该setCount重新呈现了包括Example在内的整个组件。
如果Example是其自己的组件,则滚动位置将不会刷新,因为它不再取决于计数状态。
此处的工作示例: https://codesandbox.io/s/react-hooks-counter-demo-hbek7?file=/src/index.js