【问题标题】:React fader component fade direction not changing反应推子组件淡入淡出方向不改变
【发布时间】:2021-04-25 15:44:26
【问题描述】:

我正在尝试创建一个小组件,当它的一个方法被调用时,它会在它的子组件之间消失。我一直在关注this 代码,但它支持任意数量的孩子。到目前为止,我有这个:

export const Fader = React.forwardRef<FaderProps, Props>((props, ref) => {
    const children = React.Children.toArray(props.children);

    const [currentChild, setCurrentChild] = useState({
        child: props.startIndex || 0,
        direction: 1,
    });
    let nextChild = 0;

    const fadeNext = (): void => {
        queueNextFade(); //Queues the next fade which fades in the next child after the current child has faded out

        setCurrentChild({
            child: currentChild.child,
            direction: +!currentChild.direction,
        });
        nextChild = currentChild.child + 1;
    }

    const fadePrev = (): void => {
    }

    const fadeTo = (index: number): void => {

    }

    const queueNextFade = (): void => {
        setTimeout(() => {
            setCurrentChild({
                child: nextChild,
                direction: +!currentChild.direction,
            });

        }, props.fadeTime || 500)
    }

    useImperativeHandle(ref, () => ({ fadeNext, fadePrev, fadeTo }));

    return (
        <div>
            {
                React.Children.map(children, (child, i) => (
                    <div key={i}
                        style={{
                            opacity: i === currentChild.child ? currentChild.direction : "0",
                            transition: `opacity ${props.fadeTime || 500}ms ease-in`,
                        }}
                    >
                        {child}
                    </div>
                ))
            }
        </div>
    )
});

从逻辑上讲它确实有效,但实际发生的是第一个孩子淡出,但下一个孩子没有淡入。如果再次淡入,第二个孩子淡入然后淡出,下一个孩子淡入. (View in sandbox)

有一段时间我对为什么会发生这种情况感到困惑,因为我使用的逻辑与其他库相同。我做了一些研究,看看我是否可以让useState 变得即时,我遇到了this 的帖子,我引用了它:

即使你添加了 setTimeout 函数,虽然超时会在重新渲染发生的一段时间后运行,但 setTimeout 仍将使用之前关闭的值,而不是更新后的值.

我意识到这就是我的情况。我启动setTimeout,其中currentChild.direction1。然后发生状态更改,方向更改为0。很长一段时间后,setTimeout 完成,但它没有将方向从 0 更改为 1,而是从 1 更改为 0,因为它保持了第一次调用时的原始值,因此为什么第二个孩子不会淡入,只是保持隐形。

我可以改成:

let currentChild = {...}

并且有一个“空白”useState 来充当forceUpdate,但我知道强制更新违背了 React 的本质,无论如何可能有更好的方法来做到这一点。

如果有人能帮忙,我会很感激的

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    对于将来的任何人,我发现 this 帖子解释说 setTimeout 将使用组件初始渲染中的值 为了解决这个问题,我将setTimeout 更改为:

    setTimeout(() => {
        setCurrentChild(currentChild => ({
            child: nextChild,
            direction: +!currentChild.direction,
        }));
    
    }, props.fadeTime || 500)
    

    【讨论】:

      猜你喜欢
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多