2017-08-25 200 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