ContextAPI or Redux
API문서
https://ko.reactjs.org/docs/context.html
React를 하다보면 여러 컴포넌트를 거쳐서 자료를 전달해야 하거나, 동시에 같은 자료를 사용해야 하는 경우가 생김
- Context는 리액트 컴포넌트 간에 어떠한 값을 공유 할 수 있게 해주는 기능
- 주로 Context는 전역적(global)으로 필요한 값을 다룰 때 사용
https://olaf-go.medium.com/context-api-vs-redux-e8a53df99b8
ContextAPI
Props로만 데이터를 전달하는 것은 한계 有
- 일반적으로 컴포넌트에게 데이터 전달해 줄 때 props 통해 전달하나, 컴포넌트의 형태가 복잡하면
G에서 변경된 값을 J로 가져가려면 Root를 거쳐 J로 돌아가야 합니다.
G값을 핸들링하는 함수 또한 Root에서 선언 해야합니다.
Props를 통해 핸들링 함수를 자식 컴포넌트(JS는 변수로 함수를 전달가능) 로 전달해줘야 합니다.
- 리액트는 거의 단방향으로 동작됨, 단방향 데이터통신 (부모 ▶ 자식 은 props 사용)
- 위의 사진 처럼 가기가 힘듦..
- Vue.js도 단방향
- 앵글러만 양방향
- 방법! root에 선언하고 자식 props로 내려주고, g에서 변경되면 root 값이 바뀌고, h ▷ j 로 내려줌
ContextAPI 사용
- <select> 사용 전 App.js의 <ColorContext.Provider value={{color: 'blue'}}> 로 쓰면 결과: ContextAPI의 사용, 값: blue
createContext() 훅
- ContextAPI를 생성
const 사용할이름 = createContext(초기값)
ContextAPI.js
import { createContext, Fragment } from "react"
//컨텍스트의 기본 상태 지정
const ColorContext = createContext({color: 'red'});
export default ColorContext; //consumer, provider로 내보내지는 모양
- ContextAPI를 외부에 선언
- createContext()훅 사용해서 초기값 설정 후 변수에 집어넣고 export로 내보냄
변수 이름이 consumer, provider에서 사용하는 모양
ColorComponent.js - 자식 컴포넌트
import { Fragment } from "react";
import ColorContext from "../contexts/ContextAPI";
const ColorComponent = () => {
return(
<Fragment>
<ColorContext.Consumer>
{/* 사용할 곳: Consumer - 함수의 return 구문에 화면을 처리할 내용을 작성함 */}
{
(value) => ( /* 매개변수 value로 ContextAPI에서 사용하는 초기값이 들어옴 */
<div>
ContextAPI의 사용<br/>
값: {value.color}<br/>
</div>
)
}
</ColorContext.Consumer> {/* ContextAPI의 ColortContext 가져오기 */}
</Fragment>
)
}
export default ColorComponent;
- 사용할 곳(자식 컴포넌트)에서 import를 받고, .Consumer로 감싸기
- consumer는 사용할 곳으로 데이터를 받는 곳 - 함수의 return 구문에 화면을 처리할 내용을 작성함
- (첫번째)매개변수 value로 contextAPI에서 사용하는 초기값이 들어오고, 그 값을 띄워줌 = {value.color}
App.js - 부모 컴포넌트
import { Fragment, useState } from "react";
import ColorComponent from "./component3/ColorComponent";
import ColorContext from "./contexts/ContextAPI";
const App = () => {
/*
p.495
1. ContextAPI 외부에 선언 createContext()훅 사용
2. 자식 컴포넌트 consumer로 데이터를 받기
3. 부모 컴포넌트 provider로 데이터를 전달(변경)
자식들의 공통 component에다가 넣는 것 (사진상에서 Root 파일에서는 App)
*/
//select 태그를 만들고 useState를 활용해서 color값을 변경
const [change, setChange]= useState('선택');
const handleChange = (e) => {
setChange(e.target.value);
}
return (
<Fragment>
<ColorContext.Provider value={{color: change}}> {/* value는 props임 */}
{/* Provider는 사용할 root컴포넌트에 선언합니다. */}
<ColorComponent/>
<select onChange={handleChange}> {/* 셀렉트가 change될 때 useState로 관리 */}
<option value="blue">파랑</option> {/* e.target.value 값 = blue */}
<option value="yellow">노랑</option>
<option value="green">초록</option>
</select>
</ColorContext.Provider>
</Fragment>
)
}
export default App;
- 자식에서는 받아서 사용했고, 공유할 root component(부모)에서는 Provider로 감싸기
- 부모 컴포넌트는 provider로 데이터를 전달(변경) 하는 곳 - value값을 제어, useState를 사용해서 컬러값 변경
- 부모 컴포넌트에서 바뀌면 이 하위의 모든 컴포넌트에서는 이 컬러값(color:change) 사용 가능
ContextAPI 분리 - Provider/Consumer
- ContextAPI는 전역으로 사용할 값이기 때문에 파일을 독립적으로 분리해서 작성하도록 변경
- 하위 컴포넌트에서는 훅을 이용해서 더욱 편리하게 사용할 수 있음
useContext() 훅
- 컴포넌트에서 context API를 편하게 사용하는 훅
- 리턴은 객체이고 첫번째 값은 상태값, 두번째는 값을 저장하는 setter를 가진 객체를 반환
const {state, action} = useContext(컨택스트API객체)
구현순서
- ContextAPI2.js 생성 (Provider재정의, Consumer를 외부로 export)
- App.js에서 Provider감싸기
- A.js 훅 으로 컨텍스트 사용하기
ContextAPI2.js - 준비과정
import { createContext, useState } from "react";
// 1. 초기값 설정 - 초기값은 객체로
const UserContext = createContext({ /* 객체 안의 객체 2개(state, action) */
state: {id: 'aaa', name: 'bbb'}, /* 실제로 관리할 값, 그냥 초기값의 모형, 주석해도 상관x */
action: {
setUser: () => {}
}
})
// 2. Provider 정의 - 함수의 모형, 구조분해 할당은 반드시 children으로
const UserProvider = ({children}) => { /* 자식 요소 모두 선택하는 js의 children(반드시)을 구조분해 할당으로 받음 = children이라는 키를 가져오는 것 */
const [user, setUser] = useState({id: 'aaa', name: 'bbb'}); /* 초기값은 위의 UserContext 형식으로 */
const value = {
state: user,
action: {setUser} /* {setUser: setUser} setUser라는 키는 setUser함수를 줄인 형태 */
}
return ( /* 외부에서 사용할 Provider 리턴 */
<UserContext.Provider value={value}>{children}</UserContext.Provider>
/* 위의 저장된 value를 Provider의 props로 전달 = value={value} */
)
}
//3. 컨슈머, 프로바이더 반환
const UserConsumer = UserContext.Consumer; /* Consumer 객체를 얻어서 UserConsumer에 저장 */
export {UserProvider, UserConsumer}; /* 여러개를 반환할 때는 default 쓰지 않고, {} 사용 */
//4. 기본 export
export default UserContext; /* 외부에서 사용해야 하기 때문에 디폴트로 export */
App.js - 부모 컴포넌트
import A from "./component3/A";
import B from "./component3/B";
import { UserProvider } from "./contexts/ContextAPI2";
const App = () => {
return (
<UserProvider> {/* A, B가 children으로 들어감 */}
<A/>
<B/>
</UserProvider>
)
}
export default App;
A.js - 자식 컴포넌트
1st 사용방법 - <UserConsumer> 이용
import { UserConsumer } from "../contexts/ContextAPI2";
const A = () => {
return (
<UserConsumer>
{
(value) => (
<div>
<h3>A 컴포넌트</h3>
context 안의 값: {value.state.id}<br/>
context 안의 값: {value.state.name}<br/>
</div>
)
}
</UserConsumer>
)
}
export default A;
2nd 사용방법
useContext() 훅 사용
firebase - react 배포
배포의 단계
개발(develop) - 빌드(build) - 배포(deploy)
- 개발 - 만드는 단계
- 빌드 - 어플리케이션 가동의 필요한 것들을 통합하고, 경량화 시키는 단계 (배포를 위한 준비과정)
- 배포 - 서버에 반영을 하는 것
- 웹앱을 무료로 배포하는 다양한 방법이 존재
- 깃허브 페이지
- 구글 firebase (사용)
- 기타 등
리액트 빌드
1. 프로젝트 최상위 루트에서 실행하세요. ex> 프로젝트 폴더
npm run build
2. 실행하면 build폴더가 생성됩니다.
3. build폴더 안에는 개발 단계에서 복잡한 코드를 경량화해서 index.html을 생성해 줌
4. 바로 실행하게 되면 서버가 아니라서 정상적으로 실행이 안 되므로 아래 명령어로 1회용 서버로 실행.
npx serve -s build
=> 이건 서버로 한번 켜보는 작업
5. http://localhost:3000으로 들어가보면 빌드된 결과물이 나옴
파이어베이스 배포
npx firebase init
https://deploytest-df1dc.firebaseapp.com/
8. 이후에 배포는? 코드가 수정되었으면!
- npm run build (리액트 빌드)
- npx firebase deploy (파이어베이스에 배포)만 하면됨
오늘 하루
기억에 남는 부분
-
-
어려운 부분
-
-
문제 해결 부분
-
-