我已按照https://redux.js.org/advanced/async-actions/中的示例进行了解释,我有一个从API提取的Redux thunk操作,我需要将此信息传递给Array。
数组结构就像在initialState []下,但是我确定它在错误的位置,而且我不知道如何填充它:
import { ADD_TODO, COMPLETE_TODO, UNCOMPLETE_TODO, DELETE_TODO, EDIT_TODO } from '../actions/constants';
import fetch from 'cross-fetch'
export const REQUEST_POSTS = 'REQUEST_POSTS'
let initialState = [
{ id: 2, title: 'Hardcoded array. Not updating from Action', completed: false },
]
function requestPosts(subreddit) {
return {
type: REQUEST_POSTS,
subreddit
}
}
export const RECEIVE_POSTS = 'RECEIVE_POSTS'
function receivePosts(subreddit, json) {
console.log(subreddit);
console.log(json);
return {
type: RECEIVE_POSTS,
subreddit,
posts: json,
receivedAt: Date.now(), initialState
}
}
export const INVALIDATE_SUBREDDIT = 'INVALIDATE_SUBREDDIT'
export function invalidateSubreddit(subreddit) {
return {
type: INVALIDATE_SUBREDDIT,
subreddit
}
}
// Meet our first thunk action creator!
// Though its insides are different, you would use it just like any other action creator:
// store.dispatch(fetchPosts('reactjs'))
export function fetchPosts(subreddit) {
let uri = "http://localhost:3001/posts";
// Thunk middleware knows how to handle functions.
// It passes the dispatch method as an argument to the function,
// thus making it able to dispatch actions itself.
return function(dispatch) {
// First dispatch: the app state is updated to inform
// that the API call is starting.
dispatch(requestPosts(subreddit))
// The function called by the thunk middleware can return a value,
// that is passed on as the return value of the dispatch method.
// In this case, we return a promise to wait for.
// This is not required by thunk middleware, but it is convenient for us.
return fetch(uri)
.then(
response => response.json(),
// Do not use catch, because that will also catch
// any errors in the dispatch and resulting render,
// causing a loop of 'Unexpected batch number' errors.
// https://github.com/facebook/react/issues/6895
error => console.log('An error occurred.', error)
)
.then(json =>
// We can dispatch many times!
// Here, we update the app state with the results of the API call.
dispatch(receivePosts(subreddit, json))
)
}
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'loadList': {
addForum(...state,initialState)
return [...state, ...action.payload.list]; // in case payload is {list: [...]}
}
default:
return state;
}
}
// actions.js
export const loadList = () => async dispatch => { // need to install redux-thunk to get the 'dispatch' closure
try {
const data = fetch('/posts');
dispatch({type: 'loadList', payload: {list: data}});
} catch (e) {
console.log(e);
}
}
const addForum = (state, newForum) => {
const { title, completed } = newForum;
const ids = state.map(forum => forum.id);
const newId = Math.max(...ids) + 1;
const forum = {
id: newId,
title,
completed,
};
const newState = [...state, forum]
return newState
};
const completeForum = (state, forumId) => {
console.log(forumId);
const newState = state.map(forum => {
if (forum.id === Number(forumId)) {
return {
id: forum.id,
title: forum.title,
completed: false,
};
}
return forum;
});
return newState
}
const deleteForum = (state, forumId) => {
const newState = state.filter(forum => {
console.log("test", forum);
return forum.id !== forumId
});
return newState
}
const uncompleteForum = (state, forumId) => {
const newState = state.map(forum => {
if (forum.id === forumId) {
return {
id: forum.id,
title: forum.title,
completed: true,
};
}
return forum;
});
return newState
}
const editForum = (state, updateForum) => {
console.log("ini updateForum di reducer ", updateForum);
const newState = state.map(forum => {
if (forum.id === updateForum.id) {
return {
id: forum.id,
title: updateForum.title,
completed: forum.completed
};
}
return forum;
});
return newState;
}
const forumReducer = (state = initialState, action) => {
switch(action.type) {
case ADD_TODO: return addForum(state, action.payload);
case COMPLETE_TODO: return completeForum(state, action.payload)
case UNCOMPLETE_TODO: return uncompleteForum(state, action.payload)
case DELETE_TODO: return deleteForum(state, action.payload)
case EDIT_TODO: return editForum(state, action.payload)
default: return state;
}
};
export default forumReducer;