'자바스크립트' 애플리케이션을 위한 상태관리 라이브러리
따라서, install 필요 !
npm install redux react-redux
1. 컴포넌트에서 시작
ex. 할 일 목록에서 할 일을 '추가'하겠다 - 추가? 액션발현
2. 액션 객체가 만들어짐
리듀서 호출 : 처리해줘 리듀서!
3. 리듀서는 요구하는 로직을 처리
4. 스토어 업데이트
스토리지에서 상태가 바뀌면 렌더링됨
액션 사용자가 수행하는 작업 유형을 지정하는 자바스크립트 객체
리듀서 리액트 앱의 변경 사항을 결정하고 업데이트 상태를 반환하는 함수
스토어 전체 상태 트리를 관리하는 저장소
하나. 리덕스는 자바스크립트를 위해 나왔다
두울. 리덕스는 순환구조다
import { createStore } from "redux";
Provider 상태를 통합해서 묶는 기능
useSelector provider가 상태를 통합적으로 제공하면 고르는 기능
useDispatch 상태의 액션을 제공받는 기능
function reducer(currentState, action) {
if (currentState === undefined) {
return { number: 1 };
}
const newState = { ...currentState };
if (action.type === "PLUS") {
newState.number++;
}
return newState;
}
const myStore = createStore(reducer);
const App = () => {
return (
<>
<div>
<Left />
<Right />
</div>
</>
);
};
const App = () => {
return (
<>
<div>
<Provider store={myStore}>
<Left />
<Right />
</Provider>
</div>
</>
);
};
function Left() {
//상태객체를 전체받아서 필요한 부분만 리턴
const number = useSelector((state) => {
return state.number;
});
return (
<>
<h1>{number}</h1>
</>
);
}
function Right() {
//상태의 액션만 필요하기 때문
const dispatch = useDispatch();
return (
<>
<button
onClick={() => {
dispatch({ type: "PLUS" });
}}
>
+
</button>
</>
);
}
하나. 리듀서 함수 만들기
function reducer(현재상태, action) {
조건, 타입 등등
}
두울. reducer 저장고
세엣. Provider로 묶어두고, store에 리듀서 저장고를 담음
네엣. 업데이트 된 상태를 받아서 쓰고싶다? useSelector
다섯. 상태 액션을 받아서 쓰고싶다? useDispatch
function reducer(currentState, action) {
if (currentState === undefined) {
return { number: 1 };
}
const newState = { ...currentState };
if (action.type === "PLUS") {
newState.number++;
}
//* 여기 추가 *//
if (action.type === "MINUS") {
newState.number--;
}
return newState;
}
function Right() {
const dispatch = useDispatch();
return (
<>
<button
onClick={() => {
dispatch({ type: "PLUS" });
}}
>
+
</button>
/* 여기 추가*/
<button
onClick={() => {
dispatch({ type: "MINUS" });
}}
>
-
</button>
</>
);
}
export default function App() {
return (
<div id="container">
<h1>Root</h1>
<div id="grid">
<Provider store={store}>
<Left1></Left1>
<hr />
<Right1></Right1>
</Provider>
</div>
</div>
);
}
function reducer(currentState, action) {
if (currentState === undefined) {
return {
number: 1,
};
}
const newState = { ...currentState };
if (action.type === "PLUS") {
newState.number++;
}
if (action.type === "MINUS") {
newState.number--;
}
return newState;
}
const store = createStore(reducer);
function Left1() {
return (
<div>
<h1>Left1 </h1>
<Left2></Left2>
</div>
);
}
function Left2() {
console.log("2");
return (
<div>
<h1>Left2 : </h1>
<Left3></Left3>
</div>
);
}
function Left3() {
console.log("3");
const number = useSelector((state) => state.number);
return (
<div>
<h1>Left3 : {number}</h1>
</div>
);
function Right1() {
return (
<div>
<h1>Right1</h1>
<Right2></Right2>
</div>
);
}
function Right2() {
return (
<div>
<h1>Right2</h1>
<Right3></Right3>
</div>
);
}
function Right3() {
const dispatch = useDispatch();
return (
<div>
<h1>Right3</h1>
<input
type="button"
value="+"
onClick={() => {
dispatch({ type: "PLUS" });
}}
></input>
<input
type="button"
value="-"
onClick={() => {
dispatch({ type: "MINUS" });
}}
></input>
</div>
import { Provider, useSelector, useDispatch } from "react-redux";
function reducer(currentState, action) {
if (currentState === undefined) {
return {
isSignIn: false,
};
}
const newState = { ...currentState };
if (action.type === "SignIn") {
newState.isSignIn = true;
newState.userName = action.userName;
}
return newState;
}
const store = createStore(reducer);
<Provider store={store}>
<Form></Form>
<Service />
</Provider>
const Form = () => {
const dispatch = useDispatch();
return (
<form
onSubmit={(e) => {
e.preventDefault();
dispatch({
type: "SignIn",
userName: e.target.userName.value,
});
}}
>
<input
name="userName"
placeholder="사용자 이름을 입력하세요"
autoComplete="off"
/>
<button type="submit">Sign In</button>
</form>
);
};
const Service = () => {
const userName = useSelector((state) => state.userName);
return (
<>
{userName ? (
<p>{userName}님! 환영합니다!</p>
) : (
<p>로그인 후 이용할 수 있습니다</p>
)}
</>
);
};