未捕获(在承诺中)TypeError:无法读取未定义的属性(读取‘json’)
2022-07-03
1753
问题是,当我按下选择器来选择大洲时,它给了我这个错误/搜索购买方式工作正常,唯一的问题是选择器,这可能是因为我使用了 react-router-domV6 和 Axios 不知道
搜索购买方式工作正常 提前致谢 [1]: https://i.sstatic.net/US56E.png
Controls.jsx
import React from 'react';
import { Search } from './Search';
import {useState, useEffect} from "react";
import {CustomSelect} from './CustomSelect';
import styled from 'styled-components';
const options=
[
{value: 'Америка',label: 'Америка'},
{value: 'Європа',label: 'Європа'},
{value: 'Азія',label: 'Азія'},
{value: 'Африка',label: 'Африка'},
{value: 'Океанія',label: 'Океанія'},
{value: 'Австралія',label: 'Австралія'},
];
const Wrapper=styled.div`
display:flex;
flex-direction:column;
align-items:flex-start;
@media (min-width: 768px)
{
flex-direction:row;
justify-content:space-between;
align-items:center;
}
`;
export const Controls = ({onSearch}) => {
const [search,setSearch]=useState('');
const [region,setRegion]=useState('');
useEffect(()=>{
const regionValue = region?.value;
onSearch(search,regionValue);
// eslint-disable-next-line
},[search,region]);
return (
<Wrapper>
<Search search={search} setSearch={setSearch}/>
<CustomSelect
options={options}
placeholder='Континент'
isClearable
isSearchable={false}
value={region}
onChange={setRegion}
/>
</Wrapper>
);
};
HomePage.jsx
import React from 'react';
import axios from 'axios';
import { useState, useEffect } from 'react';
import { useNavigate,useParams } from 'react-router-dom';
import { Main } from '../components/Main';
import { Controls } from '../components/Controls';
import { ALL_COUNTRIES } from '../config';
import { List } from '../components/List';
import { Card } from '../components/Card';
import { Details } from './Details';
export const HomePage = ({countries,setCountries}) => {
const [filteredCountries,setFilteredCountries] = useState(countries);
const navigate = useNavigate();
const handleSearch =(search,region)=>{
let data=[...countries];
if(region){
data=data.filter(c=>c.region.includes(region))
}
if(search){
data=data.filter(c=>c.name.toLowerCase().includes(search.toLowerCase()))
}
setFilteredCountries(data);
};
useEffect(() => {
if(!countries.lenght)
axios.get(ALL_COUNTRIES).then(
({data})=>setCountries(data))
.then(result => result.json)
},[]);
return (
<>
<Controls onSearch={handleSearch}/>
<List>
{
filteredCountries.map((c)=>
{
const countryInfo={
img:c.flags.png,
name:c.name,
info: [
{
title:'Population',
description:c.population.toLocaleString(),
},
{
title:'Region',
description:c.region,
},
{
title:'Flag',
description:c.capital,
},
],
};
return <Card key={c.name} onClick={(e)=>{navigate(`/country/${c.name}`)}}
{...countryInfo}/>
})
}
</List>
</>
);
};
2个回答
setCountries
函数返回 void。它不会为 Promise 链的下一个 then-able 返回任何内容。如果
countries
是一个数组,那么您在访问数组长度属性时也犯了一个错误。
useEffect(() => {
if (!countries.lenght) // countries.lenght is false so resolves true always
axios.get(ALL_COUNTRIES)
.then(({ data }) => setCountries(data)) // setCountries returns undefined
.then(result => result.json) // result is undefined
}, []);
也许您的意思是检查长度,然后返回 JSON Promise
示例:
useEffect(() => {
if (!countries.length) {
axios.get(ALL_COUNTRIES)
.then(result => result.json()) // <-- invoke json()
.then(({ data }) => setCountries(data));
}
}, []);
如果我没有记错的话,
axios
函数返回的 JSON 响应数据已经“解压”,因此
result.json()
调用可能没有必要。
useEffect(() => {
if (!countries.length) {
axios.get(ALL_COUNTRIES)
.then(({ data }) => setCountries(data));
}
}, []);
Drew Reese
2022-07-03
我找到了答案,我只是将
useEffect
拆分为搜索和选择器
useEffect(() => {
if (!countries.length)
axios.get(ALL_COUNTRIES).then(({ data }) => setCountries(data));
// eslint-disable-next-line
}, []);
useEffect(() => {
handleSearch();
// eslint-disable-next-line
}, [countries]);
也许是由于
useEffect
限制
Michael Hamar
2022-07-04