【问题标题】:React useState causes render loopReact useState 导致渲染循环
【发布时间】:2019-12-09 20:08:12
【问题描述】:

我正在获取数据并尝试使用useState 挂钩将响应存储在状态中。当我从 getRouteDirection 函数中设置 selectedRouteDirection 时,渲染会在无限循环中运行。如何使用 useState 设置状态并只渲染一次?

import React, { useState, Fragment, useEffect } from 'react';

const parser = require('xml-js');

const RouteSelect = props => {
    const { routes } = props;

    const [selectedRouteName, setRouteName] = useState('');
    const [selectedRouteDirection, setRouteDirection] = useState('');

    useEffect(() => {
        if(selectedRouteName) {
            getRouteDirection();
        }
    });

    const onChangeHandler = event => {
        setRouteName({ name: event.target.value });
    }

    const getRouteDirection = () => {

        const filteredRoute = routes.filter(route => route.Description._text === selectedRouteName.name);
        const num = filteredRoute[0].Route._text;

        let directions = [];
        fetch(`https://svc.metrotransit.org/NexTrip/Directions/${num}`)
            .then(response => { 
                return response.text();
            }).then(response => {
                return JSON.parse(parser.xml2json(response, {compact: true, spaces: 4}));
            }).then(response => { // offending block
                directions = response.ArrayOfTextValuePair.TextValuePair;
                // console.log(directions);
                setRouteDirection(directions);    
            })
            .catch(error => {
                console.log(error);
            });

        console.log(selectedRouteDirection);
    }

    const routeOptions = routes.map(route => <option key={route.Route._text}>{route.Description._text}</option>);

    return (
        <Fragment>
            <select onChange={onChangeHandler}>
                {routeOptions}
            </select>
        {selectedRouteName ? getRouteDirection() : null} 
        </Fragment>
    );
};

export default RouteSelect;

【问题讨论】:

  • 你给我们看的代码没有调用selectedRouteDirection
  • @AndyRay 我添加了一个控制台日志来显示我可能想要调用它的位置;我还可以在设置值的同一代码块中调用日志,它会无限循环。
  • 如果你想在组件挂载后只获取一次数据,你应该在 useEffect(() => { fetch data here }, []} 中进行。
  • @DominikTargosz 我仅在根据选项选择获得所需值后才运行该功能。

标签: javascript reactjs infinite-loop


【解决方案1】:

因为你在返回值中调用getRouteDirection(),而是使用useEffect调用getRouteDirection()

 ...

 useEffect(() => getRouteDirection());

 return (
        <Fragment>
            <select onChange={onChangeHandler}>
                {routeOptions}
            </select>
         //some thing 
        </Fragment>
    );

解释getRouteDirection() 会在每次被调用时改变状态,当状态改变时,这将导致再次调用getRouteDirection(),以此类推。

【讨论】:

  • 我可以有条件地运行它吗?我目前只有在设置另一个状态值后才调用它。您可以在三元模板表达式中看到这一点。
  • @lane 当然,将您的状态作为 useEffect 的第二个参数传递给数组
  • 在调用setRouteName方法后调用getRouteDirection,不应该直接在函数组件中
  • @Ali 从 changeHandler 调用 getRouteDirection 返回未定义。我更新了我的代码以显示我现在在 useEffect 中调用 getRouteDirection。结果还是一样。从同一位置调用控制台的无限循环。
猜你喜欢
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 2020-10-22
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
相关资源
最近更新 更多