繁体   English   中英

ReactJS 如何在 Props 值更改后运行 useEffect 但只运行一次

[英]ReactJS How to Run useEffect After Props Value Changes But Only Run It Once

我正在使用 Google Places API 运行附近搜索,然后进行详细搜索以获取返回的每个地点的小时数据。 当我进行附近搜索时,我收集所有 placeId 并将它们作为道具传递给我运行详细搜索的组件。 我使用 useEffect ReactJs 挂钩对我的 nodeJs 和 Express 后端进行 fetch 调用,并在该 fetch 调用的主体中发送地点 ID。 我循环遍历所有 ID,并将每个 ID 的 API 调用添加到后端的 promise 数组,然后将结果发送回前端。

这非常适合我的需要。 问题是我通过将 [props.placeIds] 作为回调传递给 useEffect 挂钩,在 placeId 道具值更改上调用此 useEffect。 在 useEffect 挂钩中有一个回调使 API 调用在用户运行应用程序时连续运行。 这一点,再加上每个调用中有 15 个以上的 Id 的事实,使得该应用程序每分钟运行数千次 API 调用,我认为这在生产中会非常昂贵。

我知道如果我将一个空白数组传递给 useEffect 钩子,它只会运行一次。 问题是,当我执行此操作时,useEffect API 调用在它获取任何导致应用程序崩溃的 placeId 之前运行。

我怎样才能使 useEffect API 调用等待 props.placeIds 更改然后只运行一次?

这是我对后端的 JSX fetch 调用:

useEffect(() => {
    fetch('/api/place-details-search', {
        method: 'POST',
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            placesId: props.placeIds,
            dayNumVal: props.dayNumVal,
            numOfPlaces: props.placeIds.length,
        })
    }).then(response => response.json()).then(data => {
        setPlaceHours(data.placeHourText)
    })
}, [props.placeIds])

这是我的 nodeJS 和 express 代码,它循环遍历数据并将其发送回前端:

app.post('/api/place-details-search', (req, res) => {
    const dayNumVal = req.body.dayNumVal
    const numOfPlaces = req.body.numOfPlaces
    const placeIds = req.body.placeId
    let placeHourText = [];
    let placeHourName = [];
    let promises = [];
    let parsedDayNumVal
    if (dayNumVal == 0) {
        parsedDayNumVal = 6
    } else {
        parsedDayNumVal = dayNumVal - 1
    }
    for (var i = 0; i < numOfPlaces; i++) {
        promises.push(
            axios.get('https://maps.googleapis.com/maps/api/place/details/json?place_id=' + placeIds[i] + '&fields=name%2Copening_hours&key=' + process.env.REACT_APP_GOOGLE_MAPS_API_KEY).then(response => {
                if (response.data.result !== undefined) {
                   placeHourText.push(response.data.result.opening_hours.weekday_text[parsedDayNumVal]);
                }
                if (response.data.result !== undefined) {
                    placeHourName.push(response.data.result.name)
                }
            })
        )
    }

    Promise.all(promises).then(() => {
        const placeHourTextTwo = []
        for (var i = 0; i < placeHourText.length; i++) {
            let parsedPlaceHourText = placeHourText[i]
            parsedPlaceHourText = parsedPlaceHourText.split("y").pop()
            placeHourTextTwo.push([placeHourName[i], parsedPlaceHourText])
        }
        res.send({ placeHourText: placeHourTextTwo })
    });

});

将 [props.placeIds] 作为 useEffect() 的依赖项意味着:嘿效果,除非 props.placeIds更改,否则请不要运行,所以如果您的 setPlaceHours(data.placeHourText) function 更新 props.placeIds 那么它是无限的循环案例。 一个可能的解决方案是传递从 placeIds 派生的另一个道具,但它不会在每个 API 调用中更新

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM