2017-08-25 198 views
1

我有一個期待藝術家對象列表的ReactJS。我讀了ReactJS文檔,並發現這一點:在ComponentDidMount上進行異步API調用

reactjs docs

所以我想,好吧,我會從componentDidMoun()方法內火過我fetchArtists()行動(我使用終極版)。

我這樣做,但由於某種原因,它不工作。我回來的藝術家名單是undefined,甚至在記錄員的想法中,我可以看到藝術家被退回。

CODE

這裏的應用容器組件。

class App extends Component { 
    componentDidMount() { 
    this.props.dispatch(ArtistsListActions.fetchArtists()); 
    } 

    render() { 
    return (
     <div className="App"> 
     <Header /> 
     <Route exact path="/" render={routeProps => <ArtistList {...routeProps} artists={this.props.artists} />} /> 
     <Route exact path="/artist/:artistUrlName" component={Artist} /> 
     </div> 
    ); 
    } 
} 

ArtistList.propTypes = { 
    artists: PropTypes.array.isRequired 
}; 

const mapStateToProps = function(state) { 
    console.log('The state is:'); 
    console.log(state); 
} 

export default connect(mapStateToProps)(App); 

mapStateToProps()方法中的console.log(state);應該顯示我裝藝術家的狀態,但我不這樣做,artists是在這一點上一個空數組。

console screenshot

UPDATE

我做了什麼,你都提出關於我的mapStateToProps()方法返回一個選項,但仍然無法正常工作。我已經捕獲了this screencast中發生的情況。

+0

你mapStateToProps函數需要返回一個對象將React組件的道具作爲屬性。您沒有返回任何內容,因此出現「未定義」錯誤消息。 –

+0

@PatrickHund,但是當我'console.log(state)',我不應該至少看到那裏的藝術家嗎? – Ciwan

+1

不,不是第一次渲染組件。如果使用_componentDidMount_派遣一個動作,即裝置(1)的組件被提供,而且附加到DOM(2)了Redux動作被分派(3)的數據被取出(4)的狀態下與所提取的數據來更新( 5)組件再次呈現,從狀態 –

回答

2

由於Redux不會從mapStateToProps方法獲得預期結果,因此應該返回要合併到Component props的Object。它被視爲開發者的失敗,因此Redux打破了循環,不再處理事件,迫使dev修復它。

人們也爲this.props.dispatch(ArtistsListActions.fetchArtists())快捷方式,如果傳遞函數作爲第二個參數進行連接,將派遣內自動換行,並做出以下道具可用的包裹功能:

class App extends Component { 
    componentDidMount() { 
    this.props.fetchArtists(); 
    } 

    render() { 
    return (
     <div className="App"> 
     <Header /> 
     <Route exact path="/" render={routeProps => <ArtistList {...routeProps} artists={this.props.artists} />} /> 
     <Route exact path="/artist/:artistUrlName" component={Artist} /> 
     </div> 
    ); 
    } 
} 

ArtistList.propTypes = { 
    artists: PropTypes.array.isRequired 
}; 

const mapStateToProps = function(state) { 
    console.log('The state is:'); 
    console.log(state); 
    const artists = state.artists.artists && state.artists.artists.verified; 
    return {artists: artists || []}; 
} 

const mapDispatchToProps = { 
    fetchArtists: ArtistsListActions.fetchArtists; 
} 

export default connect(mapStateToProps, mapDispatchToProps)(App); 
+0

感謝@MaxVorobjev,查看正在發生的更新問題 – Ciwan

+0

發生這種情況是因爲渲染方法期望藝術家是Array,而state.artists.artists.verified有時未定義。這個問題可以按上述,在回答參見修改'mapStateToProps' –

+0

能否請你告訴我這裏發生了什麼? 'state.artists.artists && state.artists.artists.verified;' – Ciwan

1

錯誤在你的axios調用之前被拋出。初始狀態與您api的響應形狀不匹配。

你可以嘗試,並通過您actionCreators正常化這或更新您的inital狀態相匹配的API:

const initialState = { 
    isFetching: false, 
    fetchComplete: false, 
    artists: {artists: {verified:[]}}, 
    error: null 
}; 

爲了完整,這是mapStateToProps,如果你改變你的初始狀態,你將需要:

const mapStateToProps = function(state) { 
    console.log(state); 
    return { 
     artists: state.artists.artists.verified 
    } 
} 
+0

什麼是檢查我的'狀態'對象的簡單方法?藝術家陣列可能位於'state.artists.artists.verified'下,但我還不確定,我該如何檢查?做完你的建議後,我[出現此錯誤](https://www.screencast.com/t/sJX7vU7CAF)。 – Ciwan

+0

我們可以看到你的actionCreator爲ArtistsListActions - 你也沒有將映射調度到道具 – hairmot

+0

當然是[這是](https://gist.github.com/Ciwan1859/c4020b33f353cd3cdfd461240b46e4c5)。是不是'mapDispatchToProps()'只是馬克斯提到的一個短手? – Ciwan

0

所以,你可能忘了派遣道具......

class App extends Component { 
    componentDidMount() { 
    this.props.fetch(); //Call just your mapped dispatch 
    } 

    render() { 
    return (
     <div className="App"> 
     <Header /> 
     <Route exact path="/" render={routeProps => <ArtistList {...routeProps}  artists={this.props.artists} />} /> 
     <Route exact path="/artist/:artistUrlName" component={Artist} /> 
     </div> 
    ); 
    } 
} 

ArtistList.propTypes = { 
    artists: PropTypes.array.isRequired 
}; 

const mapStateToProps = function(state) { 
    console.log('The state is:'); 
    console.log(state); 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
     fetch:() => dispatch(ArtistsListActions.fetchArtists()) 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(App); //Pass new method here