Skip to content

Instantly share code, notes, and snippets.

@james-gardner
Created August 10, 2020 08:43
Show Gist options
  • Save james-gardner/4adf5da192a683a6348603d8c195f970 to your computer and use it in GitHub Desktop.
Save james-gardner/4adf5da192a683a6348603d8c195f970 to your computer and use it in GitHub Desktop.
Articles
import React, { useReducer, useState, useEffect } from 'react'
import PropTypes from 'prop-types'
/** */
export const articleReducer = (state, action) => {
switch(action.type) {
case 'SET_CURRENT_ARTICLE':
return {
...state,
currentArticleId: action.payload.articleId
}
case 'SET_ARTICLE_CONTENT':
return {
...state,
articles: new Map([
...state.articles,
[action.payload.articleId, action.payload.content ]
])
}
default:
throw new Error(`Action ${action.type} not handled`)
}
}
/** */
export const setCurrentArticleId = articleId => ({
type: 'SET_CURRENT_ARTICLE',
payload: articleId
});
exprt const setArticleContent = (articleId, content) => ({
type: 'SET_ARTICLE_CONTENT',
payload: {
articleId,
content
}
})
/** */
export const Article = ({
articleId
}) => {
// In lieu of an outer-component or a context use state directly here.
const [{ currentArticleId, articles }, dispatch ] = useReducer(articleReducer, {
currentArticle: null,
articles: new Map()
})
useEffect(() => {
const loadArticle = async articleId => {
try {
const res = await axios.get(`/article/${articleId}`)
dispatch(setArticleContent(articleId, res.data)
} catch (err) {
// Set error in state or use another effect hook to capture errors.
// Alternatively hold the error in the reducer.
}
}
if (currentArticleId) {
loadArticle(currentArticleId)
}
}, [currentArticleId])
// If loading from a route we probably want the article id from props.
useEffect(() => {
dispatch(setCurrentArticle(articleId))
}, [])
return (
<div>
<h4>{article?.title}</h4>
<div>{article?.content}</div>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment