스토어(Store)의 상태(State)를 변경
한다. 즉, state변경함수와 같은 의미의 역할을 한다.수정 방법
을 미리 정의 해놓는 역할을 한다.🍎 reduce 사용 방법
1) store에 담은
state초기값
을 변수로 빼주고, createStore의 인자에 reducer를 넣는다
let store = createStore(reducer)
➡ state초기값을 담는 공간에 reducer 넣기2)
state 데이터
를 변수에 담기
const initState = "state초기값 담아주기" ;
3)
reducer 함수
생성 ➡ 인자 2개 받는다( 1.state초기값 지정, 2.action)function reducer(state=initState, action) { // state 데이터의 수정 조건을 if문으로 걸어주고, 수정된 state를 리턴한다 if( 액션.type === 수정방법이름 ) { 변경 과정 (1.state deepcopy ➡ 2.state변경) return 수정된state } // else로 항상 state값을 return 한다(무조건!!!!!) ➡ 변경되지 않으면 기본 state를 출력해야함 else { return state } };
4) state데이터를 가져올 컴포넌트에서 state변경을 해준다
props.dispatch( {액션(객체형태)} 을 인수로 받는다 )
❗ 순서:
(1) 기본 state데이터 변수에 담기(initState)
(2) reducer함수 생성하기(안에 조건문을 통해 변경조건과 기본 state return 해주기)
(3)let store = createStore(reducer)
해주기 (🪓reducer 함수 밑에 써주기)
객체
형태로 되어 있으며, state상태를 변화시킬 때 이 객체를 참조하여 변화를 일으킨다. 액션을 store에 전달하는 과정을 디스패치(dispatch)라고 한다.props.dispatch( {action객체} )
🐻 reducer & dispatch 적용 예시
// index.js // redux import { BrowserRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; // (1) state초기값을 변수에 담아준다(여러개면 배열형식) let initState = [ // state초기값을 객체로 여러개(배열)담음. {id: 0, name: 멋진신발, quan: 2}, {id: 1, name: 예쁜신발, quan: 3}, {id: 3, name: 귀여운신발, quan: 1} ] // (2) reducer 함수를 생성한 뒤, state초기값과 action을 인자에 담는다 function reducer(state=initState, action) { // state변경 조건 정의 if( action.type === '수량증가') { // state변경 내용 정의 let copy = [...state]; // deepcopy copy[0].quan++; // 변경 내용 return copy // 수정된state 리턴 } else if { // default로 기본state 리턴하도록 정의 return state } } // (3) store를 생성 후, store에 reducer를 담는다 const store = createStore(reducer) ReactDOM.render( <BrowserRouter> <Provider store={store}> // state초기값을 담은 store변수를 provider에 담는다 <App /> </Provider> </BrowserRouter>, document.getElementById('root') ); // Cart.js import React from 'react'; import { connect } from 'react-redux'; // import 해주기 const Cart = (props) => { return ( <div className="Cart"> // 코드 생략 { props.state.map( (a, i) => { return ( <tr key={i}> <td>{i+1}</td> <td> { props.state[i].name } </td> <td> { props.state[i].quan } </td> // 버튼을 누르면 state의 수량(quan)이 증감함 <button onClick={ () => { props.dispatch( {type: '수량증가'} )}}> + </button> // dispatch 인수에서 Ruduce로 넘길 객체 = action // dispatch내 action은 객체 형태이다 </tr> ) }) } </div> ); }; function cartInfo(state) { return { // state데이터를 state라는 이름의 props로 등록하는 것. state: state } }; export default connect(cartInfo) (Cart)
combineReducers
를 사용한다// index.js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; // redux import { BrowserRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import { combineReducers, createStore } from 'redux'; // combineReducers import하기 // 첫 번째 state & reducer let initState = [ {id: 0, name: 멋진신발, quan: 2}, {id: 1, name: 예쁜신발, quan: 3}, ] function reducer(state=initState, action) { if( action.type === '수량증가') { let copy = [...state]; // deepcopy copy[0].quan++; // 변경 내용 return copy // 수정된state 리턴 } else { return state } } // 두 번째 state & reducer function reducer2(state=true, action) { if(action.type === 'close') { state = false; return state } else { return state } } // 두 개의 reducer를 합쳐준다(combineReducers) const store = createStore( combineReducers({reducer, reducer2}) ) ❗ combineReducer를 사용할 때는 (1) import 해온다 (2) store인자 안에 묶어준다(인자로 reducer들을 복수로 받는다. 중괄호 감싸주기) ReactDOM.render( <BrowserRouter> <Provider store={store}> // state초기값을 담은 store변수를 provider에 담는다 <App /> </Provider> </BrowserRouter>, document.getElementById('root') ); // Cart.js import React from 'react'; import { connect } from 'react-redux'; // import 해주기 const Cart = (props) => { return ( <div className="Cart"> // 코드 생략 { props.state.map( (a, i) => { return ( <tr key={i}> <td>{i+1}</td> <td> { props.state[i].name } </td> <td> { props.state[i].quan } </td> // 버튼을 누르면 state의 수량(quan)이 증감함 <button onClick={ () => { props.dispatch( {type: '수량증가'} )}}> + </button> // dispatch 인수에서 Ruduce로 넘길 객체 = action // dispatch내 action은 객체 형태이다 </tr> // reducer2로 받아온 state데이터를 활용한 조건문 { props.alertState === true // 하단에 props화 해놓음 ? ( <div className="alert"> <p>지금 구매하시면 신규할인 20%</p> <button onClick={() => {props.dispatch( {type: 'close'} )}}>닫기</button> // state데이터를 수정요청하는 dispatch 지정(state변경) </div> ) : null } ) }) } </div> ); }; // reducer를 2개 받는다. 인자로 받은 state에는 2개의 reducer가 들어있다 function cartInfo(state) { return { state: state.reducer // 첫 번째 reducer의 state데이터를 props 로 등록 alertState: state.reducer2 // 두 번째 reducer의 state데이터를 props로 등록 } }; export default connect(cartInfo) (Cart)