설치
npm install react-redux
yarn add react-redux
import { createStore } from "redux" 로 불러온다.
그리고 무조건 const store = createStore(reducer)를 만들어야 한다.
바로 저장소를 만드는 것이다.
그리고 안에 reducer를 만들어야 하는데, reducer는 유일하기 저장소의 값을 변경할 수 있는 함수라고 생각하면 된다.
reducer의 이름은 마음대로 바꿔도 된다.
reducer는 두 개의 인자가 들어온다.
currentState, action.
여기서 action은 나중에 나오는 useDispatch로 action에 접근하여 state값을 바꿀 수 잇는 것이고, currentState는 현재 state를 나타낸다.
초기값을 잡을 때는 currentState를 undefined이라고 가정하고 잡는 것도 필요한 것 같다.
또한 action에는 무조건 type이 들어와야 한다.
여기서 중요한 점은!!
redux는 각각의 state의 변화가 불변해야하기 때문에 무조건 복사를 해서 사용하거나 원본을 변화시키지 않는 새로운 객체 및 배열을 만드는 것이 중요하다.
그래서 spread나 filter함수를 사용한다.
function reducer(currentState, action) {
//reducer에는 2개의 인자가 온다. 현재의 state값과 action!! //! return값이 새로운 state의 값이 된다.
if (currentState === undefined) {
return {
number: 1, //number라는 state값이 기본적으로 1이다라고 지정!! undefined일 때 적용(약간 useState() 느낌, 초기값 정해주는 것 같은 느낌.)
};
}
const newState = { ...currentState }; //redux는 각각의 state의 변화가 불변해야하기 때문에, 무조건 복사본을 사용한다!! 그렇기 때문에 spread 연산자를 사용하거나 filter를 사용한다.
if (action.type === "PLUS") {
//right3에서 useDispatch로 action에 접근하여 type을 지정했을 때, reducer는 그 action을 이용해서 state값을 변경시킬 수 있다.
newState.number++;
}
return newState;
}
const store = createStore(reducer);
Provider로 감싼 애한테 store를 전달해주겠다는 뜻.
만약 left1을 컴포넌트로 넣고 left1에 left2를 컴포넌트로 넣고 left3을 컴포넌트로 넣었을 때, left1만 Provider로 감싸줘도 left2와 left3에서 store의 사용이 가능하다.
여기서 중요한 점 !
Provider에는 store={store}가 꼭 들어가야 한다.
export default function App() {
return (
<div id="container">
<h1>Root</h1>
<div id="grid">
<Provider store={store}>
{/*반드시 Provider에는 store가 들어와야하는데, 그 store에는 우리가 지정한 store가 들어와야 하는 것이다. //! 아래 두 개의 컴포넌트에 전달해주겠다. */}
<Left1></Left1>
<Right></Right>
</Provider>
</div>
</div>
);
}
useSelector를 쓴 곳에서 props로 받겠다 할 때 쓰는 것
useSelector는 함수를 인자로 받아야 한다.
변수 이름이나 useSelector에 들어오는 parameter 이름은 아무 상관이 없다.
const Left3 = (props) => {
// function f(state) {
// return state.number; //! state값에서 number를 쓰겠다. 아래 인자와 같은 함수
// }
const number홍왕열 = useSelector((state김소라) => state김소라.number); // 여기서 App에서 props로 받겠다. //! useSelector는 함수를 인자로 받아야 한다. 변수 이름이나 useSelector에 들어오는 이름이나 아무 상관 없다.
return (
<div>
<h1>Left3: {number홍왕열}</h1>{" "}
{/*만약에 console.log로 부모와 함께 다르게 해서 찍어보았을 때, left3만 console.log가 찍힌다. 즉, 이것만 렌더링이 되고 부모는 렌더링이 되지 않는다. */}
</div>
);
};
export default Left3;
action을 이용하여 reducer를 호출한다.
dispatch에는 무조건 type이 들어간다.
const Right3 = (props) => {
const dispatch = useDispatch(); //action을 이용하여 reducer를 호출한다.
return (
<div>
<h1>Right3</h1>
<input
type="button"
value="+"
onClick={() => {
dispatch({ type: "PLUS" }); //dispatch에는 무조건 type이 들어가야 한다!!
}}
/>
</div>
);
};
import React, { useState } from "react";
import Left1 from "./Left";
import "./style.css";
import Right from "./Right";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch, connect } from "react-redux";
//Provider = 어떤 component들에게 제공할 것인가에 대한 가장 바깥쪽 울타리를 정의
//useSelector = 어느 component에 무선으로 연결하고 싶을 때 사용하는 것!! //! 지금 여기서는 Left3에 들어간다.
function reducer(currentState, action) {
//reducer에는 2개의 인자가 온다. 현재의 state값과 action!! //! return값이 새로운 state의 값이 된다.
if (currentState === undefined) {
return {
number: 1, //number라는 state값이 기본적으로 1이다라고 지정!! undefined일 때 적용(약간 useState() 느낌, 초기값 정해주는 것 같은 느낌.)
};
}
const newState = { ...currentState }; //redux는 각각의 state의 변화가 불변해야하기 때문에, 무조건 복사본을 사용한다!! 그렇기 때문에 spread 연산자를 사용하거나 filter를 사용한다.
if (action.type === "PLUS") {
//right3에서 useDispatch로 action에 접근하여 type을 지정했을 때, reducer는 그 action을 이용해서 state값을 변경시킬 수 있다.
newState.number++;
}
return newState;
}
const store = createStore(reducer);
export default function App() {
return (
<div id="container">
<h1>Root</h1>
<div id="grid">
<Provider store={store}>
{/*반드시 Provider에는 store가 들어와야하는데, 그 store에는 우리가 지정한 store가 들어와야 하는 것이다. //! 아래 두 개의 컴포넌트에 전달해주겠다. */}
<Left1></Left1>
<Right></Right>
</Provider>
</div>
</div>
);
}
//APP.js
import React from "react";
import "./style.css";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch, connect } from "react-redux";
const Right3 = (props) => {
const dispatch = useDispatch(); //action을 이용하여 reducer를 호출한다.
return (
<div>
<h1>Right3</h1>
<input
type="button"
value="+"
onClick={() => {
dispatch({ type: "PLUS" }); //dispatch에는 무조건 type이 들어가야 한다!!
}}
/>
</div>
);
};
export default Right3;
//right3
import React from "react";
import "./style.css";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch, connect } from "react-redux";
const Left3 = (props) => {
// function f(state) {
// return state.number; //! state값에서 number를 쓰겠다. 아래 인자와 같은 함수
// }
const number홍왕열 = useSelector((state김소라) => state김소라.number); // 여기서 App에서 props로 받겠다. //! useSelector는 함수를 인자로 받아야 한다. 변수 이름이나 useSelector에 들어오는 이름이나 아무 상관 없다.
return (
<div>
<h1>Left3: {number홍왕열}</h1>{" "}
{/*만약에 console.log로 부모와 함께 다르게 해서 찍어보았을 때, left3만 console.log가 찍힌다. 즉, 이것만 렌더링이 되고 부모는 렌더링이 되지 않는다. */}
</div>
);
};
export default Left3;
//left3