React Context API
context = state 보관함
context 가져오는 법 : let 변수명 = createContext() (createContext는 import해줘야 한다)
state공유를 원하는 것을 감싸준다 = <변수명.Provider>
value{} 안에 보내고 싶은 state명을 쓴다
보내고 싶은 state를 export해준다
받고싶은 파일에서 import 해준다
해당 파일에서 보관함을 해체(state들이 남는다)
* 위와 같이 받아오면 useContext(변수명)을 통해 해당 파일의 어느 위치에서든 사용 가능
React Redux (Redux toolkit 설치)
Redux = 보관함
Redux 설치 : npm install @reduxjs/toolkit react-redux
따라서 파일(store.js)을 생성
해당 파일에
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: { }
})
입력
index.js 파일에서 <Provider>태그 묶고, store에 해당 store.js 넣기
* Provider과 store 모두 import
React Redux 보관 및 사용
Redux 쓰는 이유 : 컴포넌트간 state공유가 편해짐
store에 state 보관(생성)하는 방법 :
store에 state 등록하는 방법 :
store에 있는 state 가져오는 방법 :
import { configureStore, createSlice } from '@reduxjs/toolkit'
let user = createSlice({
name : 'user',
initialState : 'kim'
})
let stock = createSlice({
name : 'stock',
initialState : [
{id : 0,
name : 'White and Black',
count : 2},
{id : 2,
name : 'Grey Yordan',
count : 1}
]
})
export default configureStore({
reducer: {
user : user.reducer,
stock : stock.reducer
}
})
import { Table } from "react-bootstrap";
import { useSelector } from "react-redux";
function Cart(){
let a = useSelector((state) => { return state })
console.log(a.stock)
return(
<div>
<Table>
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>수량</th>
<th>변경하기</th>
</tr>
</thead>
<tbody>
{
a.stock.map(function(a, i){
return(
<tr>
<td>{a.id}</td>
<td>{a.name}</td>
<td>{a.count}</td>
<td>asdf</td>
</tr>
)
})
}
</tbody>
</Table>
</div>
)
}
export default Cart;
실행 결과
React Redux state 변경
state 변경하는 방법
state 변경 함수 만들기 :
1. reducer : {} 을 통해 함수를 만든다. (여러함수 생성 가능)
2. 만든 함수를 export 한다
해당 state명.actions를 하고, 안에 있는 변경 함수들을 작성해 export 한다
3. 만든 함수 import해서 사용
* useDispatch() = store.js로 요청보내주는 함수다.
import { configureStore, createSlice } from '@reduxjs/toolkit'
let user = createSlice({
name : 'user',
initialState : 'kim',
reducers : {
changeName(state){
return 'john ' + state;
}
}
})
export let {changeName} = user.actions
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0,
name : 'White and Black',
count : 2},
{id : 2,
name : 'Grey Yordan',
count : 1}
]
})
export default configureStore({
reducer: {
user : user.reducer,
cart : cart.reducer
}
})
import { Table } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { changeName } from "./../store.js";
function Cart(){
let state = useSelector((state) => { return state })
let dispatch = useDispatch()
return(
<div>
{state.user}의 장바구니
<Table>
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>수량</th>
<th>변경하기</th>
</tr>
</thead>
<tbody>
{
state.cart.map(function(a, i){
return(
<tr key={i}>
<td>{a.id}</td>
<td>{a.name}</td>
<td>{a.count}</td>
<td>
<button onClick={() => {
dispatch(changeName())
}}>+</button>
</td>
</tr>
)
})
}
</tbody>
</Table>
</div>
)
}
export default Cart;
실행 결과
React Redux state가 object/array일 경우 변경하는 방법
object/array일 경우 아래와 같이 변경 가능
* 변경함수에서 파라미터값을 받아올 수도 있다. (대신 .payload 사용)
store에 있던 파일이 길어질 경우 분할관리하는 방법
위와 같이 새로운 파일에 해당 처럼 작성해주고,
store.js에서 import로 불러와준다
findIndex 란?
* 해당 조건식을 통해, 알아서 지정한 배열에서 반복문을 돌려 맞는 인덱스 번호를 가져온다.
import { configureStore, createSlice } from '@reduxjs/toolkit'
import user from './store/userSlice.js'
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}
],
reducers : {
addCount(state, action){
let num = state.findIndex((a) => {return a.id == action.payload});
state[num].count++;
},
addItem(state, action){
state.push(action.payload)
}
}
})
export let {addCount, addItem} = cart.actions
export default configureStore({
reducer: {
user : user.reducer,
cart : cart.reducer
}
})
import { Table } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { increase, changeName} from "./../store/userSlice";
import { addCount } from "./../store.js";
function Cart(){
let state = useSelector((state) => { return state })
let dispatch = useDispatch()
return(
<div>
<h6>{state.user.name} {state.user.age}의 장바구니</h6>
<button onClick={() => {dispatch(increase(10))}}>버튼</button>
<Table>
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>수량</th>
<th>변경하기</th>
</tr>
</thead>
<tbody>
{
state.cart.map(function(a, i){
return(
<tr key={i}>
<td>{a.id}</td>
<td>{a.name}</td>
<td>{a.count}</td>
<td>
<button onClick={() => {
dispatch(addCount(a.id))
}}>+</button>
</td>
</tr>
)
})
}
</tbody>
</Table>
</div>
)
}
export default Cart;
실행 결과