reducer(리듀서)를 생성하고, createStore 메소드를 이용해서 리듀서를 스토어에 연결합니다.
// reducer.js
export default function reducer(state, action) {
if (state === undefined) { //초기값을 주려고 undefined설정
return {
user: null,
languages: [
{
name: "JavaScript",
keyword: "Web Frontend",
},
],
};
}
// main.jsx
import { legacy_createStore as createStore } from "redux";
import reducer from "./reducer.js";
const store = createStore(reducer);
사용하기 위한 컴포넌트의 상위 컴포넌트를 provider 컴포넌트로 감싸주고 store 속성에 생성해둔 스토어를 연결합니다.
// main.jsx
import { Provider } from "react-redux";
<Provider store={store}>
<App />
</Provider>
필요한 상태를 가져오기 위해서는 useSelector를 사용해서 가져온다.
//component.jsx
import { useSelector } from "react-redux";
export const Components = () => {
const languages = useSelector((state) => state.languages);
}
상태를 변화시키기 위해서는 useDispatch를 사용해서 action(액션)을 호출합니다.
//component.jsx
import { useDispatch } from "react-redux";
import { ADD_LANGUAGE } from "./action-type"
export const Components = () => {
const dispatch = useDispatch();
const addLanguage = () => {
dispatch({
type: ADD_LANGUAGE,
name: "JavaScript",
});
};
return (
<>
<button onClick={addLanguage}>추가하기</button>
</>
);
}
//reducer.js
import { ADD_LANGUAGE } from "./action-type";
export default function reducer(state, action) {
if (action.type === ADD_LANGUAGE) {
return {
...state,
languages: [
...state.languages,
{
name: action.name,
},
],
};
}
}
// action-type.js
export const ADD_LANGUAGE = "ADD_LANGUAGE";
폼의 데이터를 처리하기 어렵다.
UI 업데이트 돔에 있지 않은 데이터를 참조하는 훅이 있다. → useRef
폼과 관련된 데이터는 처리하기가 어렵다. 사용자의 이벤트를 처리하는건 어렵기 떄문에 이를 쉽게 지원하는 hook을 사용한다.
// input 요소를 생성하면 안에 value의 값이 있다.
const inputElement = document.querySelector('#myInput');
const inputValue = inputElement.value;
//useRef는 current라는 하나의 속성을 가지는 객체를 반환하는데,
//current 내부에 value의 값이 반환되도록 설계되어 있다.
inputRef = {
current: null,
};
const inputRef = useRef(null);
const addLanguage = () => {
dispatch({
type: ADD_LANGUAGE,
name: inputRef.current.value,
});
};
//input요소에 ref 속성에 ref를 연결한다.
<input type="text" ref={inputRef} onChange={addLanguage} />
import { ADD_LANGUAGE } from "./action-type
를 사용해서 매번 type을 가져오는 것은 번거롭다. 이를 개선해보자.// action-type.js
export const ADD_LANGUAGE = "ADD_LANGUAGE";
//data가 무엇이 될지 모르기 때문에 매개변수로 받아서 처리한다.
export const dispatchAddLang = (data) => ({
type: ADD_LANGUAGE,
...data,
});
// action-type.js
export const ADD_LANGUAGE = "ADD_LANGUAGE";
export const dispatchAddLang = (name, keyword) => ({
type: ADD_LANGUAGE,
name,
keyword,
});
export const ADD_LANGUAGE = "ADD_LANGUAGE";
export const EDIT_LANGUAGE = "EDIT_LANGUAGE";
export const dispatchAddLang = (name, keyword) => ({
type: ADD_LANGUAGE,
name,
keyword,
});
export const dispatchEditLang = (name, keyword) => ({
type: EDIT_LANGUAGE,
name,
keyword,
});