如何防止竞争状况引发API调用?

时间:2020-01-30 19:49:33

标签: javascript reactjs axios race-condition use-effect

我正在尝试进行axios.get调用,并使用从该调用返回的数据设置一个称为电影的const,该const保持在组件状态。但是,API调用似乎无法正常工作。来自API调用的数据永远不会填充movie const,作为回报,依赖于来自const数据的另一个函数会使返回的结果不确定,从而破坏了代码。目前,我已将电影const初始化为一个空数组,我认为可能是问题所在。我尝试更改代码并将其初始化为空字符串和null。这些变化均未产生不同的结果。电影const仍然作为一个空数组返回。有人可以发现我的错误吗?

import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

const initialMovie = {
    id: '',
    title: '',
    director: '',
    metascore: '',
    stars: [],
  };

const UpdateMovie = () => {
    const [movies, setMovies] = useState([]);
    const [specificMovie, setSpecificMovie] = useState(initialMovie);
    const { id } = useParams();

    useEffect(() => {
        axios.get('http://localhost:5000/api/movies')
        .then(res => setMovies(res.data))
        .catch(err => console.log(err))
    }, [])

    console.log(movies);

    useEffect(() => {
        const movieToUpdate = movies.find(m => `${m.id}` === id);

        if (movies !== []) {
            setSpecificMovie(movieToUpdate);
        }
    }, [movies, id])

    const handleChanges = e => {
        e.persist();
        let value = e.target.value;

        setSpecificMovie({
            ...specificMovie,
            [e.target.name]: value
        })
    };

    return (
        <div>
            <form>
                <input type="text" name="title" className="input" value={movieToUpdate.title} />
                <input type="text" name="director" className="input" value={movieToUpdate.director} />
                <input type="text" name="metascore" className="input" value={movieToUpdate.metascore} />
                <button>Submit</button>
            </form>
        </div>
    )
};

export default UpdateMovie;



1 个答案:

答案 0 :(得分:1)

您的代码很好(获取部分)。电影更新useEffect错误:

useEffect(() => {
    const movieToUpdate = movies.find(m => `${m.id}` === id);

    if (movies !== []) {
        setSpecificMovie(movieToUpdate);
    }
}, [movies, id])

电影!== []检查将始终为false,因为[]与new Array()相等(总是一个新引用)。您需要这样的支票:

if (movies.length !== 0 && movieToUpdate)

检查电影中是否包含某些内容,以及movieToUpdate是否未定义(如果未找到,查找将返回未定义)。

您甚至可以简化为仅检查:

if (movieToUpdate)