我在这里遇到问题: 当我尝试在componentDidMount中使用此代码时,总是出现此错误:Uncaught TypeError:无法读取未定义的属性'then'
这是发生错误的组件代码: 组件/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>
)
}
}
希望您能帮助我解决这个问题!
答案 0 :(得分:3)
在mapDispatchToProps
中,您的fetchPortfolio
不会返回承诺或其他任何内容。您必须在其中返回一个承诺,但是dispatch
不返回任何内容。
您必须等待mapStateToProps
您有portfolioLoaded
映射到您的道具。只需在您的componentWillReceiveProps
中检查他的价值,如果现在是真的,您可以致电this.fetchCoins