Ситуация
- Я хочу перераспределить сетку на основе высоты изображений (используя подход кладки)
- Эти изображения загружены с отложенной загрузкой
Что я хочу
- Когда изображения загружаются, они отправляют флаг, этот флаг заставляет кладку логи c перераспределять сетку, и все счастливы
- Затем, когда пользователь прокручивает, загружаются другие изображения, снова запускает флаг и кладка снова настраивает сетку
Что происходит
* const [myState, setMyState] = use State(0)
- Когда загружаются изображения I
setMyState(1)
- В кирпичной логике c у меня есть
useLayoutEffect(() =>{}, [myState])
, поэтому при изменении состояния я настраиваю сетку - Затем я сбрасываю состояние с
setMyState(0)
, так что при загрузке нового изображения оно снова будет вызывать useLayoutEffect
- НО , когда я сбрасываю состояние, оно перерисовывает изображения, поэтому изображения загружаются снова и снова вызвать
useLayoutEffect
, который снова сбрасывает состояние, создавая бесконечное l oop - Если я не сбрасываю состояние, l oop останавливается
- НО , тогда, когда новое изображение загружается с помощью прокрутки,
setMyState(1)
ничего не меняет и useLayoutEffect
не срабатывает
Так что я сейчас застрял
Это упрощенный код
import React, { useRef, useLayoutEffect, useState} from "react";
const wait = ms =>
new Promise((res, rej) => setTimeout(() => res("timed"), ms));
const Image = ({ setImageLoader }) => {
// lazy load the image with an Observer, and then changes the state
setImageLoader(1);
return <></>;
};
export default function App() {
const [imageLoaded, setImageLoader] = useState(0);
useLayoutEffect(() => {
const update_grid = async stillMounted => {
// change stuff
await wait(10000); // careful with crashing chrome
console.log("updated");
setImageLoader(0);
};
const stillMounted = { value: true };
update_grid(stillMounted);
return () => (stillMounted.value = false);
}, [imageLoaded]);
return <Image setImageLoader={setImageLoader} />;
}
Попытка 1
Я не могу изменить состояние в useLayoutEffect
, поэтому я буду менять вещи только при загрузке изображений, а не снова
Проблема
Когда я прокручиваю и более Изображения загружены, я не могу активировать useLayoutEffect больше
import React, { useRef, useLayoutEffect, useState} from "react";
const wait = ms =>
new Promise((res, rej) => setTimeout(() => res("timed"), ms));
const Image = ({ setImageLoader }) => {
setImageLoader(1);
return <>hey</>;
};
export default function App() {
const [imageLoaded, setImageLoader] = useState(0);
useLayoutEffect(() => {
// change stuff
const update_grid = async stillMounted => {
await wait(40000);
console.log("updated");
// setImageLoader(0); NOW THIS IS NOT CAUSING THE REPAINT, BUT NEITHER WHEN NEW IMAGES ARE LOADED
};
const stillMounted = { value: true };
update_grid(stillMounted);
return () => (stillMounted.value = false);
}, [imageLoaded]);
return <Image setImageLoader={setImageLoader} />;
}
Попытка 2
Если я не хочу перерисовывать, но хочу вызвать useLayoutEffect, я мог бы использовать useRef
вместо useState
import React, { useRef, useLayoutEffect, useState, useEffect } from "react";
const wait = ms =>
new Promise((res, rej) => setTimeout(() => res("timed"), ms));
const Image = ({ imageLoaded }) => {
imageLoaded.current++;
return <>hey</>;
};
export default function App() {
const imageLoaded = useRef(0);
useLayoutEffect(() => {
// change stuff
const update_grid = async stillMounted => {
await wait(10000);
console.log("updated " + imageLoaded.current);
imageLoaded.current++;
};
const stillMounted = { value: true };
update_grid(stillMounted);
return () => (stillMounted.value = false);
}, [imageLoaded.current]);
return <Image imageLoaded={imageLoaded} />;
}
Но codesandbox уже предупреждает меня, что imageLoaded.current
не вызовет повторную визуализацию компонента (даже если я более или менее этого хочу?)
Итак, в конце я вижу imageLoaded.current
увеличение при загрузке новых изображений, но useLayoutEffect
не срабатывает