REST APIからデータをロードする

私は別の小さな自転車を共有したい-まず第一に、貴重なアドバイスを得るために。 追加の例は、GitHubファンプロジェクトのソースコードにあります


プロジェクトのほとんどすべてのページは、ページコンポーネントによってラップされます。


const MyPage = () => ( <Page> Hello World </Page> ) 

外部データをロードするために、ページコンポーネントには3つの渡されたプロパティ(プロパティ)があります。



Reduxの例:


 // components/Post/PostViewPage.js const PostViewPage = ({ post, ...props }) => ( <Page {...props}> <Post {...post} /> </Page> ) const mapStateToProps = (state) => ({ post: state.postView, isNotFound: isEmpty(state.postView), }) const mapDispatchToProps = (dispatch, ownProps) => ({ onMounted: () => { const id = parseInt(ownProps.match.params.id, 10) dispatch(actions.read(id)) } }) export default connect(mapStateToProps, mapDispatchToProps)(PostViewPage) 

isLoadingフラグは、propsに明示的に渡されず、PageコンポーネントのmapStateToPropsを介してバインドされることに注意してください(これについては後で説明します)。


式について質問がある場合:


 //   - { post, ...props } //  {...props} 

...次に、MDNディレクトリを参照できます。



副作用actions.read(id)はredux-thunkを提供します:


 // ducks/postView.js const read = id => (dispatch) => { //   state.app.isLoading dispatch(appActions.setLoading(true)) //   state.postView dispatch(reset()) //     let isTimeout = false //     let isFetch = false setTimeout(() => { isTimeout = true if (isFetch) { dispatch(appActions.setLoading(false)) } }, 500) //  state.app.isLoading   500  axios(`/post/${id}`) .then(response => { const post = response.data //    state.posts dispatch(postsActions.setPost(post)) //    state.postView dispatch(set(post)) }) .catch(error => { dispatch(appActions.setMainError(error.toString())) }) .then(response => { isFetch = true if (isTimeout) { dispatch(appActions.setLoading(false)) } }) } 

データのロードが速すぎると、点滅するダウンロードインジケータの不快な視覚効果が発生します。 これを避けるために、500ミリ秒のタイマーとisTimeoutおよびisFetchフラグにロジックを追加しました。


Pageコンポーネントは、他の装飾を破棄する場合、外部データをロードするプロセスを提供します。


 // components/Page/Page.js class Page extends React.Component { _isMounted = false componentDidMount() { this._isMounted = true const { onMounted } = this.props if (onMounted !== void 0) { onMounted() } } render() { const { isNotFound, isLoading, children } = this.props if (this._isMounted && !isLoading && isNotFound) { return <NotFound /> } return ( <div> <PageHeader /> <div> {this._isMounted && !isLoading ? children : <div>...</div> } </div> <PageFooter /> </div> ) } } const mapStateToProps = (state, props) => ({ isLoading: state.app.isLoading }) export default connect(mapStateToProps)(Page) 

どのように機能しますか? 最初のレンダーパスは、_isMountedフラグをオフにして実行され、ロードインジケーターが表示されます。 次に、 ライフサイクルメソッドcomponentDidMountが実行され、_isMountedフラグがオンになり、onMountedコールバック関数が開始されます。 onMounted内では、副作用(たとえば、actions.read(id))が発生し、state.app.isLoadingフラグが有効になります。これにより、新しいレンダリングが発生します-ロードインジケーターは引き続き表示されます。 副作用内でaxios(またはフェッチ)を非同期に呼び出した後、state.app.isLoadingフラグをオフにします。これにより、新しいレンダーが発生します。ロードインジケーターを表示する代わりに、埋め込みコンポーネント(子)のレンダーが実行されます。 ただし、isNotFoundフラグの組み込みが機能する場合、ネストされたコンポーネント(子)のレンダリングの代わりに、<NotFound />のレンダリングコンポーネントが実行されます。



Source: https://habr.com/ru/post/J327422/


All Articles