[React] (8) props 전송 없이 state 공유하기
props 전송 없이 state 공유하기!
App에 있던 state를 TabContent 컴포넌트에서 사용하고 싶어지면,
App → Detail → TabContent
props 전송을 2번 해야함
⇒ Context API나 Redux같은 외부 라이브러리 사용하면 쉽게 사용가능~!
1. Context API
(1) Context API 사용법
- App.js
export let Context1 = React.createContext();
function App() {
let [inven, setInven] = useState([10,11,12]);
return (
<Context1.Provider value={ {inven} }>
<Detail shoes={shoes} />
</Context1.Provider>
)
}
- Context1로 원하는 곳을 감싸고 공유를 원하는 state를 value 안에 적기
→ Context1로 감싼 모든 컴포넌트와 그 자식컴포넌트는 state를 props 전송없이 직접 사용가능!
- Detail.js
import { useState, useEffect, useContext } from 'react';
import { Context1 } from './../App.js';
function Detail(props) {
let {inven} = useContext(context1);
return (
<div>{inven}</div>
)
}
- Context1을 import하고 useContext() 안에 담기
(2) Context API 특징
▶ 현업에서는 Context API 활용 X
- state 변경 시 쓸데없는 컴포넌트까지 전부 재렌더링됨
state가 변경되면 Detail 컴포넌트가 state를 쓰던말던 무조건 재렌더링 → 비효율적인 재렌더링 → 성능 이슈
- 나중에 컴포넌트 재상용이 어려움
⇒ 실제로는 외부라이브러리(Redux) 활용이 높음
2. Redux
- Redux는 props 없이 state를 공유할 수 있게 도와주는 라이브러리
(1) Redux 셋팅
[step1] Redux 설치
npm install @reduxjs/toolkit@1.8.1 react-redux
[step2] store.js 파일 생성
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: { }
})
[step3] index.js 파일 셋팅
import { Provider } from 'react-redux';
import store from './store.js';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</React.StrictMode>
);
- <Provider store={store}> 추가
▷ Redux 사용하는 이유
- store.js 파일 하나에 state들을 보관
- 모든 컴포넌트가 state를 직접 꺼내씀
→ 귀찮은 props 전송이 필요없고, 컴포넌트가 많을수록 좋음
** Redux store 안에 모든걸 넣지 말기!
- 공유가 필요한 state만 추가하기
- 컴포넌트간 공유가 필요없으면 그냥 useState() 써도됨
(2) Redux 활용
- store.js
import { createSlice } form "@reduxjs/toolkit";
let user = createSlice({
name : 'user',
initialState : 'kim',
reducers : {
changeName(state) {
return 'john ' + state
}
}
})
export default configureStore({
reducer: {
user : user.reducer
}
})
export let { changeName } = user.actions;
- createSlice : useState 역할
- state 하나를 slice라고 부름
- reducers : state를 수정해주는 함수
- configureStore : state 등록
- export state 변경함수
- App.js
import { useSelector, useDispatch } from 'react-redux';
import { changeName, increase } from './../store.js';
function App() {
let state = useSelector((state) => { return state });
let a = useSelector((state) => state.user );
let dispatch = useDispatch();
return (
<div>
{state.user.name}({state.user.age})의 장바구니
<burron onClick={()=>{
dispatch(changeName()
}}>이름수정</button>
</div>
)
}
- let state : 모든 state 호출
- let a : 원하는 state 호출
- useDispatch() : store.js로 요청보내주는 함수(액션 처리하는 로직)
- dispatch(state변경함수()) → dispatch로 꼭 감싸야함!
(3) 파라미터문법 활용
- store.js
import { createSlice } form "@reduxjs/toolkit";
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
increase(state, action) {
state.age += action.payload
}
}
})
export default configureStore({
reducer: {
user : user.reducer
}
})
export let { increase } = user.actions;
- action.payload : 파라미터자리에 넣은 자료들
- App.js
import { useSelector, useDispatch } from 'react-redux';
import { changeName, increase } from './../store.js';
function App() {
return (
<div>
<burron onClick={()=>{
dispatch(increase(100)
}}>+</button>
</div>
)
}
## 코딩애플 React part2 강의 내용 ##