반응형
비동기작업 어디서 하느냐가 제일 중요하다.
- 액션을 분리
- dispatch를 할때 비동기 작업 해준다.
- 리듀서는 동기적인것
- dispatch도 동기적인것
App.js
import './App.css';
import TodoListContainer from './containers/TodoListContainer'
import TodoFormContainer from './containers/TodoFormContainer'
import UserListContainer from './containers/UserListContainer';
function App() {
return (
<div className="App">
<header className="App-header">
<UserListContainer/>
<TodoListContainer />
<TodoFormContainer />
</header>
</div>
);
}
export default App;
reducer.js
import { combineReducers } from 'redux'
import todos from './todos'
import filter from './filter'
import users from './users'
const reducer = combineReducers({
todos,
filter,
users
})
export default reducer;
actions.js
export const ADD_TODO = "ADD_TODO"
export const COMPLETE_TODO = 'COMPLETE_TODO';
// {type : ADD_TODO , text: '할일'}
export function addTodo(text) {
return {
type: ADD_TODO,
text,
};
}
// {type : COMPLETE_TODO , text: 3} > 완성된 index 값
export function completeTodo(index) {
return {
type: COMPLETE_TODO,
index,
};
}
export const SHOW_ALL = 'SHOW_ALL';
export const SHOW_COMPLETE = 'SHOW_COMPLETE';
export function showAll() {
return {type:SHOW_ALL};
}
export function showComplete() {
return {type: SHOW_COMPLETE};
}
//users
//깃헙 api 호출 시작
export const GET_USERS_START = 'GET_USERS_START';
//깃헙 api 호출이 성공적으로 들어온 경우
export const GET_USERS_SUCCESS = 'GET_USERS_SUCCESS';
//깃헙 api 호출이 실패한 경우
export const GET_USERS_FAIL = 'GET_USERS_FAIL';
export function getUsersStart() {
return {
type: GET_USERS_START
};
}
export function getUsersSuccess(data) {
return {
type: GET_USERS_SUCCESS,
data,
};
}
export function getUsersFail(error) {
return {
type: GET_USERS_FAIL,
error,
};
}
users.js
import { GET_USERS_FAIL, GET_USERS_START, GET_USERS_SUCCESS } from "../actions";
const initialState = {
loading: false,
data: [],
error: null
};
export default function users(state = initialState, action) {
if(action.type === GET_USERS_START){
return {
...state,
loading: true,
error: null,
};
}
if(action.type === GET_USERS_SUCCESS){
return {
...state,
loading: false,
data: action.data,
};
}
if(action.type === GET_USERS_FAIL){
return {
...state,
loading: false,
error: action.error,
};
}
return state;
}
UserList.jsx
import { useEffect } from "react"
import axios from "axios";
export default function UserList({users , start, success, fail}) {
useEffect(() => {
async function getUsers(){
try {
start()
const res = await axios.get('https://api.github.com/users');
success(res.data);
}catch(error){
fail(error);
}
}
getUsers();
},[start, success, fail]);
if(users.length === 0){
return <p>현재 유저 정보 없음</p>
}
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.login}</li>
))}
</ul>
);
}
UserListContainer.jsx
import { useCallback } from "react";
import { useDispatch } from "react-redux";
import { useSelector } from "react-redux"
import UserList from "../components/UserList"
import { getUsersFail, getUsersStart, getUsersSuccess } from "../redux/actions";
export default function UserListContainer(){
const users = useSelector((state) => state.users.data);
const dispatch = useDispatch();
const start = useCallback(() => {
dispatch(getUsersStart());
}, [dispatch]);
const success = useCallback((data) => {
dispatch(getUsersSuccess(data));
}, [dispatch]);
const fail = useCallback((error) => {
dispatch(getUsersFail(error));
}, [dispatch]);
return <UserList users={users} start={start} success={success} fail={fail} />
}
더 쉽게 만들기
객체 모아서 하나로 전달하기
비동기 로직을 container로 넣어주고
userList는 데이터를 받아서 보여주는 역할만 한다.
userList.jsx
import { useEffect } from "react"
export default function UserList({users , getUsers}) {
useEffect(() => {
getUsers();
},[getUsers]);
if(users.length === 0){
return <p>현재 유저 정보 없음</p>
}
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.login}</li>
))}
</ul>
);
}
userListContainer.jsx
import { useCallback } from "react";
import { useDispatch } from "react-redux";
import { useSelector } from "react-redux"
import UserList from "../components/UserList"
import { getUsersFail, getUsersStart, getUsersSuccess } from "../redux/actions";
import axios from "axios";
export default function UserListContainer(){
const users = useSelector((state) => state.users.data);
const dispatch = useDispatch();
const getUsers = useCallback(async() => {
try {
dispatch(getUsersStart());
const res = await axios.get('https://api.github.com/users');
dispatch(getUsersSuccess(res.data)); ;
}catch(error){
dispatch(getUsersFail(error));
}
},[dispatch]);
return <UserList users={users} getUsers={getUsers} />
}
반응형
'개발(라이브러리,프레임워크) > react.js & react native' 카테고리의 다른 글
redux-devtools (0) | 2022.02.02 |
---|---|
리덕스 미들웨어 (0) | 2022.02.01 |
Redux 를 React에 연결(라이브러리x) (0) | 2022.01.21 |
Redux 개요, 사용 (0) | 2022.01.20 |
Hooks (0) | 2022.01.09 |