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.