![](/img/trans.png)
[英]Unhandled Rejection (TypeError): {(intermediate value)}.filter is not a function
[英]Unhandled Rejection (TypeError): planets.filter is not a function
我使用redux来管理状态。
在我的app.js中,有一个promise函数。
它用于获取行星的名称,直径和rotation_period
我把这个promise函数改成了后面的问题
this.props.onRequestPlanets():
删除了构造函数()并设置了行星,isPending为this.props
我的网站显示错误
未处理的拒绝(TypeError):planets.filter不是一个函数
这是图片:
我该怎么办?
app.js中的Promise函数:
componentDidMount() {
const urls = [
'https://swapi.co/api/planets/',
'https://swapi.co/api/planets/?page=2',
'https://swapi.co/api/planets/?page=3',
'https://swapi.co/api/planets/?page=4',
'https://swapi.co/api/planets/?page=5',
'https://swapi.co/api/planets/?page=6',
'https://swapi.co/api/planets/?page=7'
]
Promise.all(urls.map(async url => {
const response = await fetch(url);
const morePlanets = await response.json();
var combinedArrayOfPlanets = this.state.planets;
combinedArrayOfPlanets.push(morePlanets.results);
var sortedArrayOfPlanets = combinedArrayOfPlanets
.flat()
.sort((a, b) => a.name.localeCompare(b.name));
this.setState({planets: sortedArrayOfPlanets})
}))
.catch(error =>
console.log('Error during fetching of planets:', error)
);
}
我的app.js:
import React,{Component} from 'react';
import {connect} from 'react-redux';
import CardList from '../Components/CardList';
import SearchBox from '../Components/SearchBox';
import Scroll from '../Components/Scroll';
import './App.css';
import {setSearchField,requestPlanets} from '../action'
const mapStateToProps=state=>{
return{
searchField:state.searchPlanets.searchField,
planets:state.requestPlanets.planets,
isPending:state.requestPlanets.isPending,
error:state.requestPlanets.error
}
}
const mapDispatchToProps=(dispatch)=>{
return {
onSearchChange:(event)=>dispatch(setSearchField(event.target.value)),
onRequestPlanets:()=>dispatch(requestPlanets())
}
}
class App extends Component{
componentDidMount() {
this.props.onRequestPlanets();
}
render()
const {searchField,onSearchChange,planets,isPending}=this.props;
if (isPending) {
return <div className='tc'><h1>Loading</h1></div>;
}
const filteredPlanets = planets.filter(planet=>{
return planet.name.toLowerCase().includes(
searchField.toLowerCase())
||
planet.diameter.toLowerCase().includes(
searchField.toLowerCase())
||
planet.rotation_period.toLowerCase().includes(
searchField.toLowerCase())
})
return (
<div className='tc'>
<h1 className='f2'>StarWarPlanet</h1>
<SearchBox searchChange={onSearchChange}/>
<Scroll>
<CardList planets = {filteredPlanets}/>
</Scroll>
</div>
);
}
}
export default connect(mapStateToProps,mapDispatchToProps)(App);
我的action.js:
import{
CHANGE_SEARCH_FIELD,
REQUEST_PLANETS_PENDING,
REQUEST_PLANETS_SUCCESS,
REQUEST_PLANETS_FAILED
}from './constants.js'
export const setSearchField=(text)=>({
type:CHANGE_SEARCH_FIELD,
payload:text
})
export const requestPlanets = ()=>(dispatch)=>{
dispatch({type:REQUEST_PLANETS_PENDING})
fetch('https://swapi.co/api/planets/')
fetch('https://swapi.co/api/planets/?page=2')
fetch('https://swapi.co/api/planets/?page=3')
fetch('https://swapi.co/api/planets/?page=4')
fetch('https://swapi.co/api/planets/?page=5')
fetch('https://swapi.co/api/planets/?page=6')
fetch('https://swapi.co/api/planets/?page=7')
.then(response =>response.json())
.then(data =>dispatch({type:REQUEST_PLANETS_SUCCESS,payload:data}))
.then(error =>dispatch({type:REQUEST_PLANETS_FAILED,payload:error}))
}
我的reducers.js:
import{
CHANGE_SEARCH_FIELD,
REQUEST_PLANETS_PENDING,
REQUEST_PLANETS_SUCCESS,
REQUEST_PLANETS_FAILED
}from './constants.js'
const initialStateSearch={
searchField:''
}
export const searchPlanets=(state=initialStateSearch,action={})=>{
switch(action.type){
case CHANGE_SEARCH_FIELD:
return Object.assign({},state,{searchField:action.payload})
default:
return state;
}
}
const initialStatePlanets={
isPending:false,
planets:[],
error:''
}
export const requestPlanets = (state=initialStatePlanets,action={})=>{
switch(action.type){
case REQUEST_PLANETS_PENDING:
return Object.assign({},state,{isPending:true})
case REQUEST_PLANETS_SUCCESS:
return Object.assign({},state,{planets:action.payload,isPending:false})
case REQUEST_PLANETS_FAILED:
return Object.assign({},state,{error:action.payload,isPending:false})
default:
return state;
}
}
fetch期望一个对象作为第二个参数。 当您执行操作时会出现错误:
fetch('https://swapi.co/api/planets/',
'https://swapi.co/api/planets/?page=2',
'https://swapi.co/api/planets/?page=3',
'https://swapi.co/api/planets/?page=4',
'https://swapi.co/api/planets/?page=5',
'https://swapi.co/api/planets/?page=6',
'https://swapi.co/api/planets/?page=7')
您正在添加字符串作为第二个,第三个...参数,这是错误的。
此外,由于您现在将请求数据保存在商店中并通过mapStateToProps接收,因此您应该更改渲染:
const {planets} = this.state;
至:
const {planets} = this.props;
另外,做的时要小心:
var combinedArrayOfPlanets = this.state.planets;
状态应该是不可变的,你不是在这里创建新对象,而只是向combinedArrayOfPlanets添加对this.state.planets的引用。 因此,当您稍后更改combinedArrayOfPlanets时,您实际上正在改变状态。 你可以这样做:
var combinedArrayOfPlanets = [...this.state.planets];
此外,您应该以与在初始状态下创建行星的方式相同的方式从商店获取行星,而不是:
planets:state.requestPlanets.planets,
应该:
planets:state.planets,
这样你就可以从减速器获得行星,但不会获得.json文件中的额外行星。 我建议你在将它们保存到商店之前,从减速器中的.json添加那些额外的行星。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.