【问题标题】:Dispatch works every other time in children in a loop in useeffectDispatch 每隔一次在子进程中循环使用效果
【发布时间】:2021-01-25 04:15:34
【问题描述】:

我最近开始学习 React。我在 UseEffect 中使用调度时遇到问题,它位于循环中的子级内部。我不能发布所有项目,但下面的代码:

在主页上显示在线商店产品。在一个单独的组件中,有一张使用地图循环显示的小卡片:

<Row className='mt-20'>
  {products.map(product => (
    <ProductItem key={product._id} product={product} history={history} />
  ))}
</Row>

子组件代码:

const ProductItem = ({ product, history }) => {
    const dispatch = useDispatch()

    const reviewList = useSelector(state => state.reviewList)
    const { reviews } = reviewList

    useEffect(() => {
        let clean = false

        if (!clean) dispatch(listReviewsDetailsByProductId(product._id))

        return () => (clean = true)
    }, [dispatch, product])

    const productRate =
        reviews.reduce((acc, item) => item.rating + acc, 0) / reviews.length || 0

    return (
        <Col xl='3' sm='6'>
            <Card>
                <Card.Body>
                    <div
                        className={'product-img position-relative ' + styles.wrapperImage}
                    >
                        <Link to={'/product/' + product.slug}>
                            {product.images[0] && (
                                <img
                                    src={product.images[0].path}
                                    alt=''
                                    className='mx-auto d-block img-fluid'
                                />
                            )}
                        </Link>
                    </div>
                    <div className='mt-4 text-center'>
                        <h5 className='mb-3 text-truncate'>
                            <Link to={'/product/' + product.slug} className='text-dark'>
                                {product.name}{' '}
                            </Link>
                        </h5>
                        {reviews && (
                            <div className='mb-3'>
                                <StarRatingsCustom rating={productRate} size='14' />
                            </div>
                        )}
                        <ProductPrice price={product.price} newPrice={product.newPrice} />
                    </div>
                </Card.Body>
            </Card>
        </Col>
    )
}

我使用调度操作从服务器获取特定产品的评论,然后计算评级并显示它。不幸的是,它每隔一段时间就会起作用,评级出现,然后消失。非常感谢您的帮助!

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。 在 SingleProduct 中(由 Context.Consumer 创建) 在路线中(在 Root.jsx:96)

【问题讨论】:

    标签: javascript reactjs react-redux react-hooks


    【解决方案1】:

    问题在于clean 变量不是组件状态的一部分。它只存在于useEffect 回调的范围内,并且每次效果运行时都会重新创建。

    clean 的用途是什么?什么时候应该将它设置为trueuseEffect 钩子的清理功能仅在组件卸载时运行,因此不适合像这样设置 boolean 标志。

    为了每个产品调度一次,我们可以消除它,只依赖依赖数组。我使用的是product_.id 而不是product,这样它只有在 id 更改时才会重新运行,但其他属性更改不会触发它。

        useEffect(() => {
            dispatch(listReviewsDetailsByProductId(product._id))
    
        }, [dispatch, product._id])
    

    如果此clean 状态有某种用途,则需要使用useState 创建它,以便在重新渲染时保持相同的值。你需要弄清楚你会在哪里打电话给setClean。即使 product 属性更改为新产品,此代码也只会对每个组件调用一次调度,这可能不是您想要的。

        const [clean, setClean] = useState(false);
    
        useEffect(() => {
    
            if (!clean) {
               dispatch(listReviewsDetailsByProductId(product._id))
               setClean(true);
            }
    
        }, [dispatch, product._id, clean, setClean])
    

    【讨论】:

    • 谢谢!我经常看到这个错误,在我看来,我并不完全理解 spa 的工作原理。例如,在另一种情况下,我在循环中的一个小产品卡内调用 const dispatch = useDispatch (),然后在单击时将其作为参数传递给函数 () => addToCartHandler (product, setTooltip,派遣)。之后,当您转到其他页面时,此警告再次出现。你能解释一下卸载是如何工作的吗?我不明白,例如,我可以在地图中的组件内使用调度吗?我会很感激!我在上面添加了示例错误。
    • 当您有一个仅在特定条件下呈现的组件(例如,如果没有用户,则显示登录名)并且当组件仍在执行异步操作时条件更改为 false 时,通常会发生该警告.
    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 2019-04-20
    • 2015-10-13
    相关资源
    最近更新 更多