产品加载到 redux 商店后,UseEffect 不会重新渲染页面

Posted

技术标签:

【中文标题】产品加载到 redux 商店后,UseEffect 不会重新渲染页面【英文标题】:UseEffect not rerendring page once products loaded in redux store 【发布时间】:2021-11-07 14:31:07 【问题描述】:

我正在从事电子商务项目 (MERN)。所以我得到了 Molla 电子商务 React 模板,以获得更好的 UX/UI。

在我的根函数中,我正在获取所有产品并使用 redux 存储它们,如下所示:

const updateStore = () => 
    store.dispatch( getAllProducts() );

一切正常,直到我发现如果我第一次尝试访问产品页面(在隐身模式下使用空的本地存储)我什么也得不到,并且产品对象未定义,如果我刷新页面然后它可以工作很好。

问题是当我尝试使用空的 redux store 访问产品页面时,它不会在存储数据时等待或重新呈现。 我尝试使用useEffect() 等待产品更改重新渲染,但它不起作用。 这是我的产品页面代码:

function SingleProduct( props ) 

    let productLink= props.match.params.link;

    const product = props;

    const [productLoaded,setProductLoaded] = useState(false);

    useEffect( () => 
        if(productLoaded)
            productGallery();

            document.querySelector( '.skel-pro-single' ).classList.remove( 'loaded' );
    
            let imgLoad = imagesLoaded( ".product-main-image",  background: true  );
    
            imgLoad.on( 'done', function ( instance, image ) 
                document.querySelector( '.skel-pro-single' ).classList.add( 'loaded' );
             );
        
    , [ productLink ] )

    useEffect(()=>    
        if(product)
            setProductLoaded(true);
        
    ,[product])



    return (
        productLoaded ? 
        <>
            <Helmet>
                <title></title>
            </Helmet>

            <h1 className="d-none"></h1>
            <div className="main">
            

                <div className="page-content">
                    <div className="container">
                        <div className="product-details-top skeleton-body">
                            <div className="row skel-pro-single">
                                <div className="col-md-6">
                                    <div className="skel-product-gallery">
                                    </div>

                                     <MediaOne link= productLink  />
                                </div>

                                <div className="col-md-6">
                                    <div className="entry-summary row">
                                        <div className="col-md-12">
                                            <div className="entry-summary1"></div>
                                        </div>

                                        <div className="col-md-12">
                                            <div className="entry-summary2"></div>
                                        </div>
                                    </div>

                                      <ProductDetailOne link= productLink  /> 
                                </div>
                            </div>
                        </div>

                         <DescOne link= productLink  />

                        <h2 className="title text-center mb-4">You May Also Like</h2>

                        <RelatedProducts />
                    </div>
                </div>

                 <StickyBar link= productLink  />

                <QuickView />
            </div>
        </>
        :
        <></>
    )


function mapStateToProps( state, props ) 
    return 
        product: state.data.products.filter( product => product.link == props.link )[ 0 ]
    

export default connect(mapStateToProps)(SingleProduct);

我尝试使用 useEffect 和 productLoaded 状态等待产品更改,因为它在第一页渲染时未定义,但仍显示未定义。

【问题讨论】:

【参考方案1】:

'product' 变量,我认为,是一个对象,注意如果你使用 useEffect 会发生什么。

const a = a:123; 
const b = a:123;
(a === b) === false

如果有可能,看看 id 或字符串/数字是否改变

第一个 useEffect 将在第二个之前运行,因此当它运行时它的 productLoaded 为 false。

尝试从 props 中获取 productLoaded(您不必管理 useEffect 的异步性)。

假设产品在加载前未定义

const productLoaded = !!product;

useEffect( () => 
    if(productLoaded)
        ..."do here what you need"
    
, [ productLink, productLoaded ] )

也许你可以改变css类

<div className=`row skel-pro-single $productLoaded?"loaded":""`>

作为一个建议尝试在返回的 jsx 中使用 react 作为带有变量的模板,请不要混合 js dom 交互和 react 交互,它们可能会相互干扰(react 会尝试报告他的 dom 部分设法达到他计算的状态,因此可以覆盖您所做的更改

document.querySelector( '.skel-pro-single' ).classList.remove

【讨论】:

以上是关于产品加载到 redux 商店后,UseEffect 不会重新渲染页面的主要内容,如果未能解决你的问题,请参考以下文章

如何在数组依赖中正确使用 useEffect 挂钩。我从 redux 商店传递了状态,但我的组件仍然无限渲染

如何在页面加载时调度 redux 操作以在 useEffect 中加载数据

useEffect TypeScript 错误中的 Redux 操作?

如何使用 React hooks 和 Redux 从 useEffect 执行 store.unsubscribe

使用react redux登录后重定向用户?

Next js 应用刷新时,useEffect 不调度 redux saga 动作并更新状态