UNPKG

@25sprout/react-starter

Version:

25sprout web starter with React

84 lines (67 loc) 1.74 kB
import { createAction, handleActions, Action } from 'redux-actions'; import { useRedux } from 'util/hook/redux'; import { State as GlobalState } from './reducers'; interface Blog { author: string; pID: string; thumb_url: string; // eslint-disable-line camelcase time: string; title: string; } interface BlogPayload { list: Blog[]; } export const getBlogs = createAction<Promise<BlogPayload>>('GET_BLOGS', async () => { const data = new FormData(); data.append('num', '10'); try { const posts = await fetch('https://www.25sprout.com/bin/bloglist_2016.php', { method: 'POST', body: data, }); return posts.json(); } catch (e) { return { list: [] }; } }); export const cleanBlogs = createAction('CLEAN_BLOGS'); // For Global State usage export interface State { loading: boolean; posts: Blog[]; } export const defaultState: State = { loading: false, posts: [], }; export const reducer = { // Workaround: HandleActions 目前定義無法支援多種 action 形式 blogs: handleActions<State, any>( // eslint-disable-line @typescript-eslint/no-explicit-any { GET_BLOGS_PENDING: state => ({ ...state, loading: true, }), GET_BLOGS_FULFILLED: (state, action: Action<BlogPayload>) => ({ ...state, posts: action.payload.list, loading: false, }), CLEAN_BLOGS: state => ({ ...state, posts: [], }), }, defaultState, ), }; const blogActionsMap = { getBlogs, cleanBlogs, }; const mapHooksToState = (state: GlobalState) => ({ posts: state.blogs.posts, }); type BlogSelector = ReturnType<typeof mapHooksToState>; type BlogctionsMap = typeof blogActionsMap; export const useBlog = () => useRedux<BlogSelector, BlogctionsMap>(mapHooksToState, blogActionsMap);