В моем случае здесь я хочу избежать повторного рендеринга компонента <Checkout/>
после замены URL-адреса props.history.replace(props.match.path + '/contact-data'
для загрузки component
<ContactData/>
.
. Как видно на useEffect
когда <Checkout/>
загружается, он получает query
хвост на url
, что-то вроде этого: http://localhost:3000/checkout?cheese=0&salad=0&special=0&veggie=1
. Затем я перенаправляю на URL, который выглядит следующим образом: http://localhost:3000/checkout/contact-data
, который отображает <ContactData/>
ниже, с обоими <Checkout/>
& <ContactData/>
на экране.
Мой вопрос касается useEffect
. Если я добавлю props.location.search
в качестве зависимости useEffect
, useEffect вызовет повторный рендеринг <Checkout/>
, действуя как ComponentDidUpdate
каждый раз, когда props.location.search
изменяется.
В этом случае использования, когда я заменяю url
для загрузки <ContactData/>
, props.location.search
изменится и <Checkout/>
выполнит повторную визуализацию, если у меня будет добавлена зависимость, как описано выше.
Теперь я решил эту проблему, не добавляя зависимость к useEffect
и оставляя array
из deps
пустым, заставляя useEffect
запускаться только один раз. Это плохая практика? Будет ли правильный способ сделать это без обмана useEffect
?
useEffect(() => {
const query = new URLSearchParams(props.location.search)
const ingredients = {};
for (let param of query.entries()) {
ingredients[param[0]] = +param[1]
}
setNewOrder(ingredients)
},[props.location.search])
Даже используя useEffect
с пустым array
из dependencies
Я заметил, что <Checkout/>
все еще рендерит, но, конечно, не запускает код внутри useEffect
в этом новом цикле render
Можно ли реально избежать <Checkout/>
повторного рендеринга здесь?
import React, {useEffect, useState, Fragment, Suspense} from 'react'
import {withRouter, Route} from "react-router-dom";
import CheckoutSummary from "../../components/CheckoutSummary/CheckoutSummary";
const ContactData = React.lazy(() => import("./ContactData/ContactData"))
function Checkout(props) {
const [newOrder, setNewOrder] = useState(null);
const returnToOrderCreationHandler = () => {
props.history.goBack()
}
const confirmOrderHandler = () => {
props.history.replace(props.match.path + '/contact-data')
}
useEffect(() => {
const query = new URLSearchParams(props.location.search)
const ingredients = {};
for (let param of query.entries()) {
ingredients[param[0]] = +param[1]
}
setNewOrder(ingredients)
},[])
return (
<Fragment>
<CheckoutSummary ingredients={newOrder}
cancelCheckout={returnToOrderCreationHandler}
confirmCheckout={confirmOrderHandler}/>
<Route path={props.match.path + '/contact-data'} render={() =>
<Suspense fallback={<h1>Loading...</h1>}><ContactData/></Suspense>}/>
</Fragment>
)
}
export default withRouter(Checkout)