Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Загрузка текстур "useTexture" react-three/drei (https://javascript.ru/forum/node-js-io-js/85239-zagruzka-tekstur-usetexture-react-three-drei.html)

Raadsert 23.05.2023 18:41

Загрузка текстур "useTexture" react-three/drei
 
Здравствуйте.
Никак не могу понять в чём разница между функцией "useTexture" из "react-three/drei", и стандартного "TextureLoader" из "Three".

Пробовал их обоих в деле, но "TextureLoader" по какой-то причине не может сразу вернуть данные в параметре data. В то же время "useTexture" сразу выдаёт все данные корректно, хотя тоже работает на основе "TextureLoader".

К примеру если попробовать вот этот код:
const usetex = useTexture(url)
const texload = new THREE.TextureLoader().load(url)

console.log(usetex.source.data); // Тут всё будет в порядке и вернётся текстура
console.log(texload.source.data); // А тут вернёт null


Подскажите пожалуйста, в чём между ними разница?

Aetae 23.05.2023 23:23

Не "сразу".
Загрузка текстур - асинхронная операция. Она начинается сейчас - заканчивается когда-нибудь потом.
const usetex = useTexture(url) - запускает загрузку при первом обращении и дальше использует механизмы react для сохранения и обновления состояния по мере загрузки.
const texload = new THREE.TextureLoader().load(url) - при каждом обновлении компонента заново запускает загрузку текстуры, но никаким не дожидается результата.

Raadsert 24.05.2023 00:28

Цитата:

Сообщение от Aetae (Сообщение 552033)
Не "сразу".
Загрузка текстур - асинхронная операция. Она начинается сейчас - заканчивается когда-нибудь потом.
const usetex = useTexture(url) - запускает загрузку при первом обращении и дальше использует механизмы react для сохранения и обновления состояния по мере загрузки.
const texload = new THREE.TextureLoader().load(url) - при каждом обновлении компонента заново запускает загрузку текстуры, но никаким не дожидается результата.

А возможно ли как то исправить этот недостаток "TextureLoader" не используя "react"?

Aetae 24.05.2023 00:37

Зайти на сайт Three.js и почитать документацию в которой написано как надо использовать TextureLoader.
Тыкнуть тут вверху в Учебник и почитать как работать с асинхронностью.

Raadsert 24.05.2023 12:39

Цитата:

Сообщение от Aetae (Сообщение 552035)
Зайти на сайт Three.js и почитать документацию в которой написано как надо использовать TextureLoader.
Тыкнуть тут вверху в Учебник и почитать как работать с асинхронностью.

Асинхронность не даёт возможности имитировать такую-же работу как "useTexture". Если с начала нужно загрузить текстуры и только после этого выполнять весь код, то что, весь этот код в колбек промиса запихивать?

Aetae 24.05.2023 18:05

Raadsert,

Короткий ответ: да.
Классический ответ: вынести функцию отдельно, и передавать её в коллбэк, чтоб не было лесенки.
Современный ответ: использовать async await чтобы скрыть за ними сложность и получить "плоский" код.


useTexture использует механизмы React-фреймворка. Она не "останавливает" код и ничего не ждёт. Она после того как асинхронная загрузка выполнится внутри себя заставляет компонент отрисоваться повторно, при этом возвращая результат.
Условно:
1ый рендер компонента:
const texture = useTexture(url); // texture === null;

2ый рендер компонента триггернутый из useTexture после загрузки:
const texture = useTexture(url); // texture === текстура;

3ий и далее рендер компонента триггернутый разными причинами:
const texture = useTexture(url); // texture === текстура;

Так работает React.

Raadsert 24.05.2023 18:07

Цитата:

Сообщение от Aetae (Сообщение 552042)
Raadsert,

Короткий ответ: да.
Классический ответ: вынести функцию отдельно, и передавать её в коллбэк, чтоб не было лесенки.
Современный ответ: использовать async await чтобы скрыть за ними сложность и получить "плоский" код.

Но ведь... В случае с реактом ничего подобного не практикуется...

Aetae 24.05.2023 18:22

Raadsert, дополнил ответ. Магии не существует. Синхронный код не может быть асинхронным.

Raadsert 24.05.2023 18:50

Цитата:

Сообщение от Aetae (Сообщение 552044)
Raadsert, дополнил ответ. Магии не существует. Синхронный код не может быть асинхронным.

А что вы подразумеваете под отрисовкой? Повторную загрузку текстур?

Aetae 24.05.2023 18:56

Raadsert, нет, повторную отрисовку реакт-компонента. Сам почитай про реакт и как он работает, мне неохота тут переписывать документацию реакта или устраивать лекцию.


Часовой пояс GMT +3, время: 03:47.