React Redux 연습
14070 단어 webdevjavascriptreduxreact
전제 조건:
npx create-react-app app_name
npm i redux react-redux @reduxjs/toolkit
사용된 방법:
import { combineReducers, createStore, applyMiddleware } from "redux";
import { Provider, useSelector, useDispatch } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
1. CombineReducers
const reducer = combineReducers({
userData: userReducer,
...
<more here>
});
2. createStore(더 이상 사용되지 않음)/configureStore
const store = createStore(reducer, applyMiddleware(thunk, middelware2, middleware3, etc..)); // this is deprecated.
(OR)
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(middleware1, middleware2, etc...)
});
3. 공급자
ReactDOM.render(
<Provider store={store}>
<App></App>
</Provider>,
document.getElementById("root")
);
4. 사용 선택기
const App = () => {
const userData = useSelector((state) => state.userData); // where userData is the key name given in the combineReducers.
const userId = userData.userId;
return (
<div>
<h3>User id is {userId}</h3>
</div>
);
};
5. 디스패치 사용
const App = () => {
const dispatch = useDispatch();
const updateUserId = (ev) => {
dispatch(setUserId(ev.target.value)); // action creator
dispatch({type: "SET_USER_ID", payload: ev.target.value}); // regular dispatch
};
return (
<div>
<input type="text" value={userId} onChange={updateUserId} />
</div>
);
};
단계:
1. 동작 유형 상수를 선언합니다.
~/src/state/actionTypes.js
const actionTypes = {
user: {
SET_NEW_USER: "SET_NEW_USER",
SET_USER_ID: "SET_USER_ID"
},
counter: {
INCREASE_COUNT: "INCREASE_COUNT",
},
};
export default actionTypes;
2. 감속기를 선언합니다.
~/src/state/reducers/counterReducer.js
import actionTypes from "../actionTypes";
const counterReducer = (state = 0, action = {}) => {
switch (action.type) {
case actionTypes.counter.INCREASE_COUNT:
return state + action.payload.count;
default:
return state;
}
};
export default counterReducer;
~/src/state/reducers/userReducer.js
import actionTypes from "../actionTypes";
const userReducer = (state = { userId: 1, userData: {} }, action = {}) => {
switch (action.type) {
case actionTypes.user.SET_NEW_USER:
return {
...state,
userData: { ...action.payload },
};
case actionTypes.user.SET_USER_ID:
return {
...state,
userId: action.payload,
};
default:
return state;
}
};
export default userReducer;
3. 감속기를 결합합니다.
~/src/state/reducers/index.js
import { combineReducers } from "redux";
import userReducer from "./userReducer";
import counterReducer from "./counterReducer";
const reducer = combineReducers({
userData: userReducer,
countData: counterReducer,
});
export default reducer;
4. 결합된 리듀서와 미들웨어가 있는 경우 전달하여 스토어를 생성합니다.
~/src/state/store.js
// import { createStore, applyMiddleware } from "redux";
// import thunk from "redux-thunk";
import { configureStore } from "@reduxjs/toolkit";
import reducer from "./reducers/index";
// createStore is deprecated..
// const store = createStore(reducer, applyMiddleware(thunk));
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
});
// To add additional middlewares,
// middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(middleware1, middleware2, etc...), // thunk is inbuilt in @reduxjs/toolkit
export default store;
5. 기능 요구 사항에 따라 작업을 선언합니다.
~/src/state/actions/counterActions.js
import actionTypes from "../actionTypes";
const increaseCount = (countToIncrease) => {
return {
type: actionTypes.counter.INCREASE_COUNT,
payload: { count: countToIncrease },
};
};
export { increaseCount };
~/src/state/actions/userActions.js
import axios from "axios";
import actionTypes from "../actionTypes";
const getUser = (userId) => {
return async (dispatchMethod, getState) => {
const userResponse = await axios.get(`https://jsonplaceholder.typicode.com/users/${userId}`);
const userData = await userResponse.data;
dispatchMethod({ type: actionTypes.user.SET_NEW_USER, payload: userData });
return userData;
};
};
const setUserId = (userId) => {
return {
type: actionTypes.user.SET_USER_ID,
payload: userId,
};
};
export { getUser, setUserId };
6. 기능을 구현하고 필요에 따라 작업을 디스패치합니다.
~/src/components/counter/Counter.js
import { useSelector, useDispatch } from "react-redux";
import { increaseCount } from "./../../state/actions/counterActions";
const Counter = () => {
const counterData = useSelector((state) => state.counterData);
const dispatch = useDispatch();
const handleIncreaseCount = (count = 1) => {
dispatch(increaseCount(count));
};
return (
<div>
<h2>Counter</h2>
<h3>{counterData}</h3>
<button
onClick={() => {
handleIncreaseCount(1);
}}
style={{ marginRight: "10px" }}
>
Increase count by 1
</button>
<button
onClick={() => {
handleIncreaseCount(5);
}}
>
Increase count by 5
</button>
</div>
);
};
export default Counter;
~/src/App.js
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { getUser, setUserId } from "./state/actions/userActions";
import Profile from "./components/user/Profile";
import Counter from "./components/counter/Counter";
const App = () => {
const userData = useSelector((state) => state.userData);
const userId = userData.userId;
const [showLoader, setShowLoader] = useState(false);
const dispatch = useDispatch();
const getUserInfo = () => {
setShowLoader(true);
dispatch(getUser(userId))
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
})
.finally(() => {
setShowLoader(false);
});
};
const updateUserId = (ev) => {
dispatch(setUserId(ev.target.value));
};
return (
<div>
<input type="text" value={userId} onChange={updateUserId} />
<h3>User id is {userId}</h3>
<button onClick={getUserInfo}>Get user info</button>
<br />
{showLoader ? "loading..." : <Profile></Profile>}
<hr />
<Counter></Counter>
</div>
);
};
export default App;
7. 공급자로 전체 애플리케이션을 래핑하고 저장소를 소품으로 전달합니다.
~/src/index.js
import ReactDOM from "react-dom";
import App from "./App";
import { Provider } from "react-redux";
import store from "./state/store";
ReactDOM.render(
<Provider store={store}>
<App></App>
</Provider>,
document.getElementById("root")
);
새로고침 시 redux 상태 유지
~/src/state/store.js
~/src/index.js
단계:
1.
npm i redux-persist
2.
~/src/state/store.js
// NEW LINES START
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
// Setup persist config and persist reducer
const persistConfig = {
key: "persisted_state_data",
storage,
};
const persistedReducer = persistReducer(persistConfig, reducer);
// NEW LINES END
// UPDATED LINE START
// Pass this persisted reducer to the store configurator and disable the serializableCheck.
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
serializableCheck: false,
}),
});
// UPDATED LINE END
// NEW LINE START
// Create a persisted store along with the normal store and export both.
const persistor = persistStore(store);
// NEW LINE END
// UPDATED LINE START
export { persistor, store };
// UPDATED LINE END
3.
~/src/index.js
// Import persisted store and the regular store.
import { persistor, store } from "./state/store";
import { PersistGate } from "redux-persist/integration/react";
// Within the redux provider wrap the app with the PersistGate component and pass the persistStore.
ReactDOM.render(
<Provider store={store}>
<PersistGate persistor={persistor}>
<App></App>
</PersistGate>
</Provider>,
document.getElementById("root")
);
레포 링크: Github
추신
Reference
이 문제에 관하여(React Redux 연습), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/aydotvin/react-redux-walk-through-4il1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)