javascript - Reactjs - 未捕获的类型错误:无法读取未定义的属性“then”
问题描述
我在这里有一个问题:当我尝试在 componentDidMount 中使用此代码时,我总是收到此错误:未捕获的 TypeError:无法读取未定义的属性 'then'
这是发生错误的组件的代码:components/Portfolio.jsx
import React, { Component } from 'react'
import Header from './Header'
import { connect } from 'react-redux';
import { auth } from '../actions';
import Popup from 'reactjs-popup';
import { portfolio } from '../actions'
import thunk from 'redux-thunk'
class Portfolio extends Component {
state = {
coin: undefined,
quantity: undefined,
buy_price: undefined,
coindata: undefined,
isLoaded: undefined,
}
componentDidMount(){
// this.props.fetchPortfolio();
// this.fetchCoins();
this.props.fetchPortfolio().then(() => {
this.fetchCoins();
});
}
componentDidUpdate(prevProps) {
if(this.props.auth.user !== prevProps.auth.user) {
this.fetchCoins();
}
}
submitInvestment = (e) => {
e.preventDefault();
this.props.addInvestment(this.state.coin, this.state.quantity, this.state.buy_price);
this.props.fetchPortfolio();
this.fetchCoins();
}
fetchCoins(){
let coins = this.props.portfolio.map(coin => coin.coin).join(",");
console.log(coins);
//console.log(coins)
fetch("https://min-api.cryptocompare.com/data/pricemultifull? fsyms="+coins+"&tsyms=USD")
.then(res => res.json())
.then(
(result) => {
console.log(result)
this.setState({
isLoaded: true,
coindata: result,
})
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
...
}
}
}
const mapStateToProps = state => {
let errors = [];
if (state.portfolio.errors) {
errors = Object.keys(state.portfolio.errors).map(field => {
return {field, message: state.portfolio.errors[field]};
});
}
return {
user: state.auth.user,
auth: state.auth,
portfolio: state.portfolio.portfolio,
portfolioLoaded: state.portfolio.portfolioLoaded,
coin_symbol: state.coin,
errors
// errors
}
}
const mapDispatchToProps = dispatch => {
return {
addInvestment: (coin, quantity, buy_price) => {
return dispatch(portfolio.addInvestment(coin, quantity, buy_price));
},
deleteInvestment: (coin) => {
dispatch(portfolio.deleteInvestment(coin));
},
fetchPortfolio: () => {
dispatch(portfolio.fetchPortfolio());
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Portfolio); //
这是 actions/portfolio.js 中的 fetchPortfolio 函数:
export const fetchPortfolio = () => {
return (dispatch, getState) => {
let headers = {'Content-Type': 'application/json'}
let {token} = getState().auth
if (token) {
headers['Authorization'] = `Token ${token}`
}
return fetch('/api/coins/', {headers })
.then(res => {
if (res.status < 500) {
return res.json().then(data => {
return {status: res.status, data}
})
} else {
console.log('Server Error!')
throw res
}
})
.then(res => {
if (res.status === 200) {
dispatch({type: 'FETCH_PORTFOLIO', portfolio: res.data})
} else if (res.status === 401 || res.status === 403) {
dispatch({type: 'AUTHENTICATION_ERROR', data: res.data})
throw res.data
}
})
}
}
这是 App.js 代码:
import React, { Component } from 'react'
import {Switch, Route, BrowserRouter, Redirect, Link} from 'react-router-dom'
import { Provider, connect } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import {auth} from './actions'
import rootReducer from './reducers'
import News from './components/News'
import NotFound from './components/NotFound'
import Login from './components/Login'
import Register from './components/Register'
import Market from './components/Market'
import Portfolio from './components/Portfolio'
let store = createStore(rootReducer, applyMiddleware(thunk))
class RootContainerComponent extends Component {
componentDidMount () {
this.props.loadUser()
}
render () {
if (this.props.auth.isLoading) {
return <p>Loading..</p>
} else {
return (
<BrowserRouter>
<Switch>
<Route exact path='/' component={News} />
<Route exact path='/login' component={Login} />
<Route exact path='/register' component={Register} />
<Route exact path='/markets' component={Market} />
<Route exact path='/portfolio' component={Portfolio} />
<Route component={NotFound} />
</Switch>
</BrowserRouter>
)
}
}
}
const mapStateToProps = state => {
return {
auth: state.auth
}
}
const mapDispatchToProps = dispatch => {
return {
loadUser: () => {
return dispatch(auth.loadUser())
}
}
}
let RootContainer = connect(mapStateToProps, mapDispatchToProps) (RootContainerComponent)
export default class App extends Component {
render () {
return (
<Provider store={store}>
<RootContainer />
</Provider>
)
}
}
我希望你能帮我解决这个问题!
解决方案
在mapDispatchToProps
你的fetchPortfolio
不返回承诺或其他任何东西。您必须在其中返回一个承诺,但dispatch
不返回任何东西。
你必须等待你的道具被更新mapStateToProps
你有portfolioLoaded
哪个映射到你的道具。只需检查他在你的价值componentWillReceiveProps
,如果它是真的,现在你可以打电话this.fetchCoins
推荐阅读
- solr - Solr 禁用同义词和停用词
- asp.net-mvc - 使用 DataContextClass 添加 View 和不添加 View 有什么区别?
- java - progressDialoge 未更新
- rest - 从 Keycloak 中的 REST API 中提取角色
- apache-camel - 如何检查 Camel 消息正文是否基于流?
- java - 如何通过 AnnotationProcessor 访问 TypeUse 注释
- javascript - 如何在 oncomplete 中检查两个以上的条件
- python - 错误:预期的序列或类似数组,得到
" - html - 内联网格相关的 CSS 在 Gmail 中消失
- powershell - 无法使用 .csv 文件的数据