https://github.com/kazuma1989/proposal-react-effect-components
EffectComponents: An idea for handling async effects in the React + Redux architecture
https://github.com/kazuma1989/proposal-react-effect-components
async hooks react reactjs redux
Last synced: 3 months ago
JSON representation
EffectComponents: An idea for handling async effects in the React + Redux architecture
- Host: GitHub
- URL: https://github.com/kazuma1989/proposal-react-effect-components
- Owner: kazuma1989
- Created: 2019-12-09T02:26:10.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-07T12:37:00.000Z (over 2 years ago)
- Last Synced: 2025-01-22T09:33:05.367Z (5 months ago)
- Topics: async, hooks, react, reactjs, redux
- Language: TypeScript
- Homepage:
- Size: 1.7 MB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# EffectComponents: An idea for handling async effects in the React + Redux architecture
Wrap your async effects with a kind of components, that are called **EffectComponents**.
EffectComponents are not so special components, but:
- It is mainly composed of **useEffect** hooks for async effects
- It only returns null and renders nothingFor example:
```typescript
import { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { Dispatch } from 'redux'
import { RootState, Actions } from './reducer'export default function SearchPostsAPI() {
// Slice values from the root state.
// Tuple here is optional.
// You can use a normal object or call `useSelector` multi times.
const [query, status] = useSelector((state: RootState) => [
state.query,
state.postsStatus,
])
const dispatch = useDispatch>()// Main async effects
useEffect(() => {
;(async () => {
// Guard to avoid too many calls
if (status !== 'waiting') return// A start action
// Notify that the state should get to "loading" status
dispatch({
type: 'API.Posts.Start',
})try {
// Awaits API call completes
const posts = await fetch(
`https://jsonplaceholder.typicode.com/posts?q=${query}`,
).then<
{
userId: number
id: number
title: string
body: string
}[]
>(r => r.json())// A complete action
// Its payload contains API inputs and outputs
dispatch({
type: 'API.Posts.Complete',
payload: {
query,
posts,
},
})
} catch (error) {
// An error action
// Its payload contains API inputs and error details
dispatch({
type: 'API.Posts.Error',
payload: {
query,
error,
},
error: true,
})
}
})()
}, [query, status])return null
}
```## Motivation
In the React + Redux architecture, async effects always require a tough decision:
- _Where to place async effects?_
- _Which library should I use?_
- _Is the library not too hard to learn?_
- _Does the architecture design scale?_But even with no 3rd parties, React and Redux are themselves well designed.
We should utilize the core features at the maximum.