【问题标题】:What is the usage of material-ui useScrollTrigger with child target ref?material-ui useScrollTrigger 与子目标 ref 的用途是什么?
【发布时间】:2019-06-11 20:08:14
【问题描述】:

我正在尝试将material-ui's useScrollTriggerwindow 以外的目标一起使用,如下所示:

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>
    );
};

这会导致抛出错误,因为在调用useScrollTriggercontentRef.current 为空。这个以子元素为目标的实用程序的正确用法是什么?

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    你是对的,因为组件第一次渲染 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>
        );
    };
    

    【讨论】:

    • 完美。你能解释一下为什么这行得通,而不是我的方法吗?第一次调用 useScrollTrigger 时,scrollTarget 仍然未定义。我知道通过使用useState,当 ref 不再未定义时,该函数将再次被调用,但第一次调用不应该仍然抛出吗?是否有一些魔法可以让内部使用的效果知道状态会改变但不知道 ref 会被填充?
    • 不,没有魔法,useScrollTrigger 只能通过它给出的参数起作用,它抛出 null 而不是 undefined 的事实是由于它的实现方式。请参阅此处了解更多信息material-ui.com/components/app-bar/…。无论如何,undefined 通常都比 null 好,因为 undefined 会触发函数的默认参数行为,而 null 不会这样做。但无论如何你需要一个状态,因为当调用 ref 回调时 useRef 钩子不会导致重新渲染(除非你自己设置一个状态)。
    • 此代码对我不起作用。如果我滚动到组件/节点,我希望 scrollTrigger 为真。我认为 scrollTarget 不起作用。我检查了状态并使用 div 设置了状态,但是当我开始滚动时没有任何变化。 scrollTrigger 始终为假。有什么想法吗?
    【解决方案2】:

    对于那些感到被遗忘的打字稿用户,让我为你节省几个小时来找出合适的打字方式:

    const [scrollTarget, setScrollTarget] = useState<Node | Window | undefined>()
    const scrollTrigger = useScrollTrigger({ target: scrollTarget });
    

    【讨论】:

      【解决方案3】:

      我会尝试这样的事情:

       const scrollTrigger = useScrollTrigger(() => {{ target: contentRef.current }});
      

      【讨论】:

      • 这给了我一个Expected an assignment or function call and instead saw an expression no-unused-expressions 错误。
      猜你喜欢
      • 2021-11-19
      • 2019-10-13
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 2019-02-11
      • 2021-11-06
      • 2017-02-05
      相关资源
      最近更新 更多