React-window, как предотвратить перерисовку списка при изменении состояния?
Это мой пример песочницы кода:https://codesandbox.io/s/react-hooks-counter-demo-kevxp?file=/src/index.js
Моя проблема: список всегда будет обновляться при каждом изменении состояния внутри страницы, поэтому прокрутка всегда будет возвращаться наверх. Я хочу знать, почему это происходит, и как предотвратить такое поведение, даже если состояние списка изменилось, а затем сохранить последнюю позицию прокрутки списка
2 ответа
Я не думаю, что это проблема окна реакции.
Компонент React повторно отрисовывается, потому что происходит изменение состояния. В этом случае изменение состояния вызывается setCount (при нажатии кнопки увеличения), который повторно отображает весь компонент, включая Example.
Если Example является отдельным компонентом, позиция прокрутки не будет обновляться, потому что она больше не зависит от состояния счетчика.
Рабочий образец здесь:https://codesandbox.io/s/react-hooks-counter-demo-hbek7?file=/src/index.js
Каждый раз App
рендеринга, вы создаете совершенно новое определение для Example
составная часть. Он может делать то же самое, что и старый, но это новый компонент. Поэтому react сравнивает элемент из одного рендера с элементом следующего рендера и видит, что у них разные типы компонентов. Таким образом, он вынужден размонтировать старую и смонтировать новую, как если бы вы что-то изменили из<div>
к <span>
. Новый начинает прокручиваться до 0.
Решением является создание примера только один раз вне приложения.
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>
);
}