Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Java
- xPlatform
- NPM
- R
- Kotlin
- table
- react
- GIT
- mapreduce
- IntelliJ
- plugin
- Android
- SSL
- window
- Sqoop
- Python
- Spring
- MSSQL
- JavaScript
- Express
- 보조정렬
- Eclipse
- tomcat
- SQL
- es6
- mybatis
- SPC
- vaadin
- 공정능력
- hadoop
Archives
- Today
- Total
DBILITY
react redux redux-toolkit 본문
반응형
내년쯤 다시 볼지 모르니 기록하자.
redux-toolkit으로 여러가지 해결(?)되었다고 한다.
npm install react-redux @reduxjs/toolkit
createSlice를 쓰면 name/reducer형태의 action.type을 자동으로 생성해 준다.
action의 reducer를 export,사용하는 콤포넌트에선 import 후 dispath하면 된다.
이전 방식 dispath({type:"action type",payload:"object"}) 형태가 아닌 dispatch(userDefinedReducer(object))로 하면 된다?
Couter에 더하기,빼기를 해본다. setState없이 직접 수정이 가능한 건 Immer.js때문이라고 한다.
store를 만든다
import {configureStore, createSlice, current} from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: {value: 0},
reducers: {
plus(state, action) {
console.log(current(state),state.value);
state.value = state.value + action.payload.value
},
minus(state, action) {
console.log(current(state),state.value);
state.value = state.value - action.payload.value
}
}
})
export const {plus, minus} = counterSlice.actions;
export default configureStore({
reducer: {
couterState: counterSlice.reducer
}
})
Counter콤포넌트를 만든다.
import React from 'react';
import styled from "styled-components";
import {useDispatch, useSelector} from "react-redux";
import {plus, minus} from "./store";
const DivCounter = styled.div`
text-align: center;
`;
const ButtonCounter = styled.button`
text-align: center;
background: dodgerblue;
border: none;
color: white;
border-radius: 5px;
margin-left: 10px;
padding: 4px 10px 5px 10px;
`;
function Counter() {
const counter = useSelector(state => state.couterState);
const dispatch = useDispatch();
return (
<DivCounter>
{counter.value}
<ButtonCounter onClick={() => dispatch(plus({value: 1}))}>+</ButtonCounter>
<ButtonCounter onClick={() => dispatch(minus({value: 1}))}>-</ButtonCounter>
</DivCounter>
);
}
export default Counter;
root.render에 Provider를 설정한다.
import React from "react";
import ReactDOM from "react-dom/client";
import Counter from "./Counter";
import store from "./store";
import {Provider} from "react-redux";
const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(
<Provider store={store}>
<Counter/>
</Provider>
);
reducer는 sync, 필요하다면 createAsyncThunk를 통해 비동기 액션을 만들고 createSlice안에 extraReducers에 처리한다.
typescript를 사용하려고 보니
store정의의 기본 형태가 다음과 같다.
const store = configureStore({
reducer: {
...
}
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
위 couter sample과 비슷하게 typescript로 변경했다.
import {configureStore, createSlice, current, PayloadAction} from "@reduxjs/toolkit";
export interface TypeState {
value: number
}
const initialState: TypeState = {
value: 0
}
const counterSlice = createSlice({
name: 'counter',
initialState: initialState,
reducers: {
plus: (state: TypeState, action: PayloadAction<TypeState>) => {
console.log(current(state), state.value);
state.value = state.value + action.payload.value
},
minus : (state: TypeState, action: PayloadAction<TypeState>) => {
console.log(current(state), state.value);
state.value = state.value - action.payload.value
}
}
});
export const {plus, minus} = counterSlice.actions;
const store = configureStore({
reducer: {
counter: counterSlice.reducer,
}
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
import React, {JSX} from 'react';
import {plus, minus, RootState, AppDispatch} from "./store";
import {useDispatch, useSelector} from "react-redux";
const CounterComponent = (): JSX.Element => {
const counter = useSelector((state: RootState) => state.counter);
const dispatch = useDispatch<AppDispatch>();
console.log(counter);
return (
<div>
<label>counter</label>{` `}
{counter.value}{` `}
<button onClick={() => dispatch(plus({value: 1}))}>+</button>
{` `}
<button onClick={() => dispatch(minus({value: 1}))}>-</button>
</div>
);
}
export default CounterComponent;
반응형
'front-end & ui > react' 카테고리의 다른 글
react image src path (0) | 2023.06.09 |
---|---|
react react-toastify (0) | 2023.06.09 |
react styled component (0) | 2023.04.12 |
react cors proxy (0) | 2023.03.09 |
react v18 UseTransition, useDeferredValue hook (0) | 2022.06.07 |
Comments