【问题标题】:UseEffect not rerendring page once products loaded in redux store产品加载到 redux 商店后,UseEffect 不会重新渲染页面
【发布时间】: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 状态等待产品更改,因为它在第一页渲染时未定义,但仍显示未定义。

【问题讨论】:

    标签: reactjs redux react-redux react-hooks use-effect


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      相关资源
      最近更新 更多