Skip to content

Instantly share code, notes, and snippets.

@lmiller1990
Created May 11, 2020 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lmiller1990/0ea95cd74e9a7de86c5169e20a0fa686 to your computer and use it in GitHub Desktop.
Save lmiller1990/0ea95cd74e9a7de86c5169e20a0fa686 to your computer and use it in GitHub Desktop.
import React, { useEffect } from 'react'
import { createStore } from 'redux'
import { Provider, useDispatch, useSelector, shallowEqual } from 'react-redux'
import { ajaxBaseState, mapEntities, isLoaded } from 'flux-entities'
const fetchTodoRequest = () => ({ type: 'REQUEST' })
const fetchTodoSuccess = (payload) => ({
type: 'SUCCESS', payload
})
const fetchTodo = dispatch => {
dispatch(fetchTodoRequest())
return new Promise(res => {
setTimeout(() => {
const newTodo = { id: '2', title: 'create a custom hook' }
dispatch(fetchTodoSuccess(newTodo))
res()
}, 1000)
})
}
const rootReducer = (state, action) => {
if (action.type === 'REQUEST') {
return {
...state,
todos: {
...state.todos,
loading: true,
touched: true,
}
}
}
if (action.type === 'SUCCESS') {
return {
...state,
todos: {
...state.todos,
loading: false,
ids: [...state.todos.ids, action.payload.id ],
all: {...state.todos.all, [action.payload.id]: action.payload }
}
}
}
return state
}
const store = createStore(rootReducer, {
todos: {
...ajaxBaseState(),
all: {
1: {
title: 'do some work',
id: '1'
}
},
ids: ['1']
}
})
const Todos = () => {
const todos = useSelector(state => state.todos, shallowEqual)
return (
<ul>
{mapEntities(todos).map(x => <li key={x.id}>{x.title}</li>)}
</ul>
)
}
const WithTodos = (props) => {
const todosLoaded = useSelector(state => isLoaded(state.todos))
const dispatch = useDispatch()
useEffect(() => {
if (!todosLoaded) {
fetchTodo(dispatch)
}
}, [dispatch, todosLoaded])
if (!todosLoaded) {
return <div>Loading todos...</div>
}
return <>{props.children}</>
}
const TodosList = () => (
<WithTodos>
<Todos />
</WithTodos>
)
function App() {
return (
<Provider store={store}>
<TodosList />
</Provider>
);
}
window.store = store
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment