首页 > 解决方案 > axios调用的无限循环,React

问题描述

最近我一直在从事一个个人项目,并且发生了一些事情,我不知道为什么。当我试图调用一个函数来获取一个值时,它会一直循环,就好像数组中有无限的对象一样。我正在尝试削减此过程,但此时我不能。

你能告诉我我做错了什么吗?提前致谢

这是我的代码

const ModalBodyUpdatePreparacion: React.FC<modalBodyFormProps> = (props: modalBodyFormProps) => {

const[stockPreparaciones, setStockPreparaciones] = useState<any[]>([]);
const[nombreIng, setNombreIng] = useState('');

useEffect(() => { //I'm using this useEffect hook to obtain the values of my array, which has just two objects at the moment
    getPreparaciones();
},[stockPreparaciones.length]);

const getPreparaciones = () => {
    console.log(props.objectS);
    axios.get('https://inventario-services.herokuapp.com/invservice/stock/getone/?codigo=' + props.objectS)
    .then(result => {
        console.log(result);
        setStockPreparaciones(result.data.preparaciones);
        console.log(stockPreparaciones);
    }).catch(console.log); 
}

function getNombre(e:any){ //This is the function that I'm calling
    axios.get('https://inventario-services.herokuapp.com/invservice/stock/getone/?codigo=' + e)
    .then(result => {
        console.log('busqueda del nombre');
        console.log(result);
        setNombreIng(result.data.nombre);
        console.log(nombreIng);
    });
    console.log(nombreIng);
    return nombreIng;
}

return(
    <div>
        <Container>
            <br></br>
            <Grid columns={3} divided>
                <Grid.Row>
                    <Grid.Column>
                        <label>Nombre del ingrediente:</label>
                    </Grid.Column>
                    <Grid.Column>
                        <label>Cantidad:</label>
                    </Grid.Column>
                    <Grid.Column>
                        <label>Acciones:</label>
                    </Grid.Column>
                </Grid.Row>
                {
                    stockPreparaciones.map(st => ( //Here is where I'm going through my array, it's just about two objects
                        <Grid.Row key={st.id}>
                            <Grid.Column>
                                <Input size='small' placeholder='Nombre ingrediente' value={getNombre(st.codigo_ingrediente)} disabled  /> //Here is were I'm calling the function to get a value
                            </Grid.Column>
                            <Grid.Column>
                                <Input size='small' placeholder='Cantidad*'  value={st.cantidadxpreparacion} disabled/>
                            </Grid.Column>
                            <Grid.Column>
                            <Button variant="secondary" onClick={props.handleSubmit}>
                                Eliminar
                            </Button>
                            </Grid.Column>
                        </Grid.Row>
                    ))
                }
            </Grid>
        </Container>
        <br></br>
        <Button variant="secondary" onClick={props.handleSubmit}>
            Cancelar
        </Button>
        <Button variant="secondary" >
            Agregar preparacion
        </Button>
    </div>
);}

问题是,无论我试图获得一个独特的价值,它都会不断渲染数据......所以这有点疯狂。

这是我的控制台的一个例子:

运行函数“getNombre”的控制台示例

谢谢

标签: javascriptreactjsreact-hooksuse-effect

解决方案


问题是:

1.在渲染上调用函数:

// this will call the function on each render 
value={getNombre(st.codigo_ingrediente)}

2.getNombre功能导致重新渲染通过setNombreIng

function getNombre(e:any){ //This is the function that I'm calling
    axios.get('https://inventario-services.herokuapp.com/invservice/stock/getone/?codigo=' + e)
    .then(result => {
        console.log('busqueda del nombre');
        console.log(result);
        setNombreIng(result.data.nombre); // <--- Setting state will make re- render
        console.log(nombreIng);
    });
    console.log(nombreIng);
    return nombreIng;
}

结果:无限循环


解决方案 :

我做了一些改变:

您可以调用getNombrefromgetPreparaciones因为它依赖于它,然后您可以直接使用该值并将其保存为第一个 api 的数据

所以不需要第二个状态nombreIng

const[stockPreparaciones, setStockPreparaciones] = useState<any[]>([]);
// const[nombreIng, setNombreIng] = useState(''); // <--- NO NEED OF THIS NOW

const getPreparaciones = async () => {
    try {
        const result = await axios.get('https://inventario-services.herokuapp.com/invservice/stock/getone/?codigo=' + props.objectS);
        let data = result.data.preparaciones
        for(let i = 0 ; i< data.length ; i++ ) {
            data[i].nombreIng = await getNombre(data[i].codigo_ingrediente); // <--- WE'LL STORE IT INSIDE MAIN DATA
        }
        setStockPreparaciones(data);
    } catch(err) {
        catch(console.log); 
    }
}

const getNombre = async (e:any) => {
    const result= await axios.get('https://inventario-services.herokuapp.com/invservice/stock/getone/?codigo=' + e)
    return result.data.nombre;
}
// now you can directly access this with `st.nombreIng`
<Input size='small' placeholder='Nombre ingrediente' value={st.nombreIng} disabled  /> 

推荐阅读