Я пытаюсь использовать Использование материала-UIScrollTrigger с целью, отличной от window
, например:
export default props => {
let contentRef = React.createRef();
const scrollTrigger = useScrollTrigger({ target: contentRef.current });
return (
<React.Fragment>
<CustomHeader shrink = {scrollTrigger} />
<div ref = {contentRef}>
{props.children}
</div>
</React.Fragment>
);
};
Это приводит к возникновению ошибки, потому что contentRef.current
имеет значение null при вызове useScrollTrigger
. Как правильно использовать эту утилиту с дочерними элементами в качестве цели?
Я бы попробовал что-то вроде этого:
const scrollTrigger = useScrollTrigger(() => {{ target: contentRef.current }});
Вы были правы, так как в первый раз, когда компонент отображает contentRef.current, значение null, поэтому будет выдана ошибка.
Нам нужны две вещи: ссылка на целевой элемент и способ повторного рендеринга, чтобы наш scrollTrigger снова вычислялся. другими словами, нам нужно государство.
Следующий код будет работать
export default props => {
// please keep it undefined here to not make useScrollTrigger throw an error on first render
const [scrollTarget, setScrollTarget] = useState(undefined)
const scrollTrigger = useScrollTrigger({ target: scrollTarget });
return (
<React.Fragment>
<CustomHeader shrink = {scrollTrigger} />
<div ref = {node => {
if (node) {
setScrollTarget(node);
}
}}>
{props.children}
</div>
</React.Fragment>
);
};
Идеально. Не могли бы вы объяснить, почему это работает, а не мой подход? scrollTarget
все еще не определено, когда useScrollTrigger
вызывается в первый раз. Я знаю, что при использовании useState
функция будет вызываться снова, когда ссылка больше не будет неопределенной, но не должен ли первый вызов по-прежнему генерировать? Есть ли какое-то волшебство, с помощью которого эффект, используемый внутри, знает, что состояние изменится, но не знает, что ссылка будет заполнена?
Нет, никакого волшебства нет, useScrollTrigger работает только с параметрами, которые ему заданы, тот факт, что он выдает значение null, а не значение undefined, связан с тем, как он реализован. Подробнее см. здесь material-ui.com/components/app-bar/…. undefined в любом случае обычно лучше, чем null, потому что undefined запускает поведение параметров по умолчанию для функций, а null этого не делает. Но в любом случае вам нужно состояние, потому что хук useRef не вызывает повторную визуализацию при вызове обратного вызова ref (если только вы сами не установите состояние).
Этот код не работает для меня. Я хочу, чтобы scrollTrigger был истинным, если я прокручиваю до компонента/узла. Я думаю, что scrollTarget не работает. Я проверил состояние, и состояние устанавливается с помощью div, но ничего не меняется, когда я начинаю прокрутку. scrollTrigger всегда ложно. Есть идеи?
Для вас, пользователей машинописных текстов, которые чувствуют себя обделенными, позвольте мне сэкономить вам несколько часов вашей жизни, выясняя, как правильно печатать:
const [scrollTarget, setScrollTarget] = useState<Node | Window | undefined>()
const scrollTrigger = useScrollTrigger({ target: scrollTarget });
Это дает мне
Expected an assignment or function call and instead saw an expression no-unused-expressions
ошибку.