图像为空,无法读取属性

The image is null, cannot read properties

const url = "http://api.tvmaze.com/search/shows?q=girls";

export default function MoviesList() {
    const [movie, setMovie] = useState([]);

    useEffect( () => {
        loadData();
        }, []);
        const loadData = async () => {
            await fetch(url)
            .then(response => response.json())
            .then(data => setMovie(data))
            .catch(error => console.log(error));
        }

    function movieCard (movie) {
        return (
            <Card className="movie-card" key={movie.show.id}>
                <Card.Body>
                    <Card.Title>{movie.show.name}</Card.Title>
                    <Card.Text>{movie.show.url}
                    <Card.Img src={movie.show.image.medium} />
                    </Card.Text>
                </Card.Body>
            </Card>
        );
    }
    return (
        <>
        <h1>Movie List</h1>
        {movie.map(movieCard)}
        </>
    )
}

所以我想做的是尝试从 API 访问图像 URL 并在我的卡片组件上使用它。但是一旦我访问它,网络就会变成空白,这就是控制台上显示的内容。

知道如何解决这个问题吗?非常感谢!

当涉及到使用 API 获取时,您需要为更大的数据结构做好准备,因为我在上面的输出中只能看到 1 个项目,我将尝试说明为什么事情不起作用。

在您的 setMovie 中,您将电影设置为整个数据。

如果我们继续使用 setMovie(data[0]) 我们改为保存第一项。

未来可能会有一些调整,但现在 movie 将可以访问您的 movieCard 函数中的 urlnamemedium

问问自己是否确实需要 data[0],或者是否需要更改初始 fetch(url) 以获得 1 个特定项目。


根据您在下方的评论,您希望为每个项目显示电影卡。我将如何做到这一点将重写 abit 并制作一个 return 为每部电影调用 movieCard 然后 return 就是那个。

const [movie, setMovie] = useState([]);

我会改成 const [movies, setMovies] = useState([]); 以表明我们可能正在处理多部电影,具体取决于我们获取的内容。

我们也回到您设置状态的原始方式: setMovie(data) 因为我们现在知道您拥有所有项目。

我们接下来可以做的是像这样重写您的 return:

 return (
        <>
        <h1>Movie List</h1>
        {movies.map((movie) => (
           movieCard(movie);
        )}
        </>
    )

现在会发生的是,不再 return 调用 1 个项目调用 movieCard 函数,包含所有数据的状态将迭代并为其包含的每个电影项目创建一个 movieCard。

渲染函数在数据到达之前运行,添加一个条件,如果数组为空,则不制作卡片

function movieCard (movie) {
    if(movie !== ''){
        return (
            <Card className="movie-card" key={movie.show.id}>
                <Card.Body>
                    <Card.Title>{movie.show.name}</Card.Title>
                    <Card.Text>{movie.show.url}
                    <Card.Img src={movie.show.image.medium} />
                    </Card.Text>
                </Card.Body>
            </Card>
        );
    }
}

此外,将数据更改为数据[0],因为数据位于数组的第一个元素中

useEffect( () => {
        loadData();
        }, []);
        const loadData = async () => {
            await fetch(url)
            .then(response => response.json())
            .then(data => setMovie(data[0]))
            .catch(error => console.log(error));
        }