This my code sandbox example: =/src/index.js
My problem is: The list will always rerendering on every state change inside the page so the scroll will always back to the top. I want to know why this happen, and how to prevent this behaviour even the state of the list have changes then keep the last scroll position of the list
This my code sandbox example: https://codesandbox.io/s/react-hooks-counter-demo-kevxp?file=/src/index.js
My problem is: The list will always rerendering on every state change inside the page so the scroll will always back to the top. I want to know why this happen, and how to prevent this behaviour even the state of the list have changes then keep the last scroll position of the list
Share Improve this question asked May 30, 2020 at 4:48 My real nameMy real name 5471 gold badge5 silver badges17 bronze badges 2- 1 Always post relevant code in the question itself. – Bhojendra Rauniyar Commented May 30, 2020 at 4:59
- i post my code on codesandbox – My real name Commented May 30, 2020 at 5:03
2 Answers
Reset to default 4Every time App
renders, you are creating a brand new definition for the Example
ponent. It may do the same thing as the old one, but it's a new ponent. So react pares the element from one render with the element of the next render and sees that they have different ponent types. Thus, thus it is forced to unmount the old one and mount the new one, just as it would if you changed something from a <div>
to a <span>
. The new one begins scrolled to 0.
The solution to this is to create Example only once, outside of App.
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>
);
}
https://codesandbox.io/s/react-hooks-counter-demo-qcjgj
I don't think it's a react window problem.
A react ponent re-renders because there's a state change. In this case, the state change is caused by setCount (when you click the increment button), which re-renders the entire ponent including Example.
If Example is its own ponent, the scroll position won't get refreshed, because it no longer depends on the count state.
A working sample here: https://codesandbox.io/s/react-hooks-counter-demo-hbek7?file=/src/index.js