=================== Prepare ========================
- whenever we dispatch a function, redux pick it up and invoke it
export const fetchPostsAndUsers = () => async dispatch => {
await // need await because invoking an async function and we want to wait until it's done
dispatch( // dispatch an "async dispatch..." function, so invoke it directly
dispatch( // dispatch an "async dispatch..." function, so invoke it directly
fetchPosts() // call export const fetchPosts = ()
// and return "async dispatch => { ... }"
// and return "async dispatch => { ... }"
)
}
export const fetchPosts = () => async dispatch => {
const response = await jsonPlaceholder.get('/posts')
dispatch({type:'FETCH_POSTS', payload: response.data})
}
- redux thunk call action creator's function argument: dispatch and getState
Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.
- Lodash _.map function can map collection by given criteria ( https://lodash.com/docs/3.10.1#map)
If a property name is provided for iteratee the created _.property style callback returns the property value of the given element.
- Lodash ._uniq function can create unique array ( https://lodash.com/docs/#uniq)
Creates a duplicate-free version of an array, using SameValueZero for equality comparisons, in which only the first occurrence of each element is kept. The order of result values is determined by the order they occur in the array.
===================== Need to change =================
- Remove memoize function
export const fetchUser = (userId) => async dispatch => {
const response = await jsonPlaceholder.get(`/users/${userId}`)
dispatch({type:'FETCH_USER', payload: response.data})
}
- Create fetchPostsAndUsers function
export const fetchPostsAndUsers = () => async (dispatch, getState) => {
await dispatch (fetchPosts());
const userIds = _.uniq(_.map(getState().fetchPosts, 'userId'))
userIds.forEach(id => dispatch(fetchUser(id)))
}
- Fetch posts and users from PttPosts.js
import React, {Component} from "react";
import {connect} from 'react-redux'
import {fetchPostsAndUsers, selectPttPost} from "../actions";
import UserHeader from "./UserHeader";
class PttPosts extends Component {
componentDidMount() {
this.props.fetchPostsAndUsers()
}
renderList() {
if (this.props.postList) {
return this.props.postList.map((post) => {
return <div key={post.id}>
<div key={post.id}><a onClick={() => this.props.selectPttPost(post)}>Title:{post.title}</a></div>
<UserHeader userId={post.userId} />
</div>
});
} else {
return 'Loading...'
}
};
render() {
return <div>{this.renderList()}</div>
}
}
const mapStateToProps = (state) => {
return {postList: state.fetchPosts};
}
export default connect(mapStateToProps, { fetchPostsAndUsers, selectPttPost })(PttPosts)
- Don't need fetchUsers from UserHeader.js
import React, {Component} from "react";
import {connect} from 'react-redux'
class UserHeader extends Component {
render() {
return <div>Author: {this.props.user?.name}</div>
}
}
const mapStateToProps = (state, props) => {
return {user: state.users?.find(user => user.id === props.userId)}
}
export default connect(mapStateToProps, {fetchUser})(UserHeader)
- Duplicated requests disappear
沒有留言:
張貼留言