Ich habe eine React-Komponente, die mit Redux-Speicher verbunden ist. Ich hole Ressourcen (Beiträge) in der componentWillMount
Life-Cycle-Methode.Async-Aktion mit Redux
componentWillMount() {
this.props.fetchPosts();
}
Die Komponente wird zu Redux Store abonnieren und isFetching
und posts
aus dem Laden zu bekommen.
const mapStateToProps = (state) => {
return {
posts: getAllPosts(state),
isFetching: getIsFetchingPosts(state),
}
}
Ich mag einen Spinner zeigen, wenn es nach wie vor ist das Abrufen, so in der render
Methode würde Ich mag, dies zu tun.
render() {
if (this.props.isFetching) {
return <Spinner />
}
return this.props.posts.map(post => <PostItem key={post.id}{...post}/>)
}
aber wenn ich isFetching
in dem Verfahren render
console.log zunächst zeigt es false
und dann true
und dann schließlich false
.
Im Idealfall, wenn dieser Container zum ersten Mal rendert isFetching
Zustand ist bereits auf true
festgelegt und zeigt den Spinner. Welche Änderungen muss ich vornehmen, um dies zu ermöglichen?
Hier ist der Code für die Aktion Schöpfer und Reduzierungen
/*** Action Creator ***/
export const fetchPosts =() => (dispatch) => {
dispatch({
type: REQUEST_POSTS,
});
return axios({
method: 'get',
url: `${API_URL}/posts`,
})
.then(({data}) => {
dispatch({
type: RECEIVE_POSTS,
payload: data.posts,
})
})
.catch((response) => {
// some error handling.
});
}
/*** Reducers ***/
const initialState = {
isFetching: false,
allIds: [],
byId: {},
};
const isFetching = (state = initialState.isFetcthing, action) => {
switch (action.type) {
case REQUEST_POSTS:
return true;
case RECEIVE_POSTS:
return false;
default:
return state;
}
}
const allIds = (state = initialState.allIds, action) => {
switch (action.type) {
case RECEIVE_POSTS:
return action.payload.map(post => post.id);
default:
return state;
}
}
const byId = (state = initialState.byId, action) => {
switch (action.type) {
case RECEIVE_POSTS:
return action.payload.reduce((nextState, post) => {
nextState[post.id] = post;
return nextState;
}, {...state});
default:
return state;
}
}
const posts = combineReducers({
isFetching,
allIds,
byId,
});
export default posts;
/*** Selectors in 'posts.js' file ***/
export const getAllPosts = (state) => {
const { allId, byId } = state;
return allIds.map(id => byId[id]);
}
/*** rootReducer file ***/
import posts, * as fromPosts from './posts';
const rootReducer = combineReducers({
posts,
})
export default rootReducer;
export const getAllPosts = (state) => {
return fromPosts.getAllPosts(state.posts);
};
Vielen Dank im Voraus!
nicht wirklich klar, was fetchPosts ist Sie stellen es nicht in mapStateToProps bereit. Und was sind die Verbindungen zwischen den Posts von state und fetchPosts (funktioniert die Funktion update?). Könnten Sie das klären? – berliner
Wenn man 'isFetching = false 'am Anfang hat, ist das ein ok-Verhalten, da es nur bedeutet, dass die Aktion den Reducer noch nicht getroffen hat, dh' render' wurde aufgerufen, bevor 'fetchPosts' das Flag auf true gesetzt hat. – Igorsvee