패스트캠퍼스 한 번에 끝내는 프론트엔드 개발(Online) 강의 정리
react-router-dom 에서 제공하는 router 관련 hooks
사용해 react-router를 처리하기
useHistory
useParams
withRouter(HOC)로 감싸서 props로 받아 history에 접근
import { withRouter } from "react-router-dom";
export default withRouter(function LoginButton(props) {
function Login() {
setTimeout(() => {
props.history.push("/");
}, 1000);
}
return <button onClick={Login}>로그인 하기</button>;
});
props를 받아오지 않고 곧바로 useHistory를 통해서 해당 페이지의 history에 접근 가능
export default function LoginButton() { // props 제거
const history = useHistory(); // 현재의 history
function Login() {
setTimeout(() => {
history.push("/");
}, 1000);
}
return <button onClick={Login}>로그인 하기</button>;
}
dynamic router를 사용하는 경우, route에서 props를 받아서 해당 페이지에서
props를 통해서 route 주소에 적힌 params 부분으로 id에 접근 가능했음
export default function Profile(props) {
const id = props.match.params.id;
return (
<div>
<h2>Profile 페이지 입니다.</h2>
{id && <p>id 는 {id} 입니다.</p>}
</div>
);
}
useParams를 사용함으로서 props를 받아올 필요 없이 바로 parmas에 접근 가능
import { useParams } from "react-router";
export default function Profile() { // props 제거
const params = useParams();
const id = params.id;
console.log(id, typeof id); // 1, string
return(
<div>
<h2>Profile 페이지입니다.</h2>
{id && <p>id 는 {id} 입니다.</p>}
</div>
);
}
여러 개의 컴포넌트 사이에서 데이터를 주고 받아 렌더링되는지
npx create-react-app component-communication
<A />
컴포넌트에서 button에 onClick 이벤트를 만들고,<A />
의 state를 변경하여, <B />
로 내려주는 props를 변경<B />
의 props가 변경되면, <C />
의 props에 전달<C />
의 props가 변경되면, <D />
의 props로 전달<D />
의 props가 변경되면, <E />
의 props로 전달A컴포넌트(버튼) -> B컴포넌트 -> C컴포넌트 -> D컴포넌트 -> E컴포넌트(pros.value)
export default function A() {
const [value, setValue] = useState('아직 안 바뀜');
return (
<div>
<B value={value} />
<button onClick={click}>E의 값을 바꾸기</button>
</div>
);
function click() {
setValue('E의 값을 변경');
}
}
function B({value}) {
return (
<div>
<p>여긴 B</p>
<C value={value} />
</div>
);
}
function C({value}) {
return (
<div>
<p>여긴 C</p>
<D value={value} />
</div>
);
}
function D({value}) {
return (
<div>
<p>여긴 E</p>
<E value={value} />
</div>
);
}
function E({value}) {
return (
<div>
<p>여긴 E</p>
<h3>{value}</h3>
</div>
);
}
import './component/A';
function App() {
return(
<div className="App">
<header className="App-header">
<A />
</header>
</div>
);
}
<A />
에 함수를 만들고, 그 함수 안에 state를 변경하도록 구현, 그 변경으로 인해 p 안의 내용을 변경<B />
로 전달<B />
의 props의 함수를 <C />
의 props로 전달<C />
의 props의 함수를 <D />
의 props로 전달<D />
의 props의 함수를 <E />
의 props로 전달, <E />
에서 클릭하면 props로 받은 함수를 실행E컴포넌트(버튼) -> D컴포넌트 -> C컴포넌트 -> B컴포넌트 -> A컴포넌트(pros.value)
export default function A() {
const [value, setValue] = useState('아직 안 바뀜');
return(
<div>
<p>{value}</p>
<B setValue={setValue} />
</div>
);
}
function B({setValue}) {
return(
<div>
<p>여긴 B</p>
<C setValue={setValue} />
</div>
);
}
function C({setValue}) {
return(
<div>
<p>여긴 C</p>
<D setValue={setValue} />
</div>
);
}
function D({setValue}) {
return(
<div>
<p>여긴 D</p>
<E setValue={setValue} />
</div>
);
}
function E({setValue}) {
return(
<div>
<p>여긴 E</p>
<button onClick={click}>클릭</button>
</div>
);
function click() {
setValue('A의 값을 변경');
}
}
import './component/A1';
function App() {
return(
<div className="App">
<header className="App-header">
<A1 />
</header>
</div>
);
}
변경
하는 경우 : setState 함수를 내림표현
하는 경우 : state 자체를 내림컴포넌트 한개정도를 거쳐서 전달하는건 사실 그렇게 큰 불편함도 없지만,
만약 3~4개 이상의 컴포넌트를 거쳐서 전달을 해야 하는 일이 발생하게 된다면 이는 매우 번거로울 것입니다.
그럴 땐, 리액트의 Context API 와 이전 섹션에서 배웠던 dispatch 를 함께 사용하면 이러한 복잡한 구조를 해결 할 수 있습니다.
리액트의 Context API 를 사용하면, 프로젝트 안에서 전역적으로 사용 할 수 있는 값을 관리 할 수 있습니다.
여기서 제가 "상태" 가 아닌 "값" 이라고 언급을 했는데요, 이 값은 꼭 상태를 가르키지 않아도 됩니다.
이 값은 함수일수도 있고, 어떤 외부 라이브러리 인스턴스일수도 있고 심지어 DOM 일 수도 있습니다. (중략)Context API 를 사용해서 전역적으로 사용 할 수 있게 해주면 컴포넌트에게 함수를 전달해줘야 하는 상황에서
코드의 구조가 훨씬 깔끔해질 수 있습니다. 만약에 깊은 곳에 위치하는 컴포넌트에게 여러 컴포넌트를 거쳐서
함수를 전달해야 하는 일이 있다면 이렇게 Context API 를 사용하시면 됩니다.
context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.
일반적인 React 애플리케이션에서 데이터는 위에서 아래로 (즉, 부모로부터 자식에게) props를 통해 전달되지만,
애플리케이션 안의 여러 컴포넌트들에 전해줘야 하는 props의 경우 (예를 들면 선호 로케일, UI 테마)
이 과정이 번거로울 수 있습니다. context를 이용하면, 트리 단계마다 명시적으로 props를 넘겨주지 않아도
많은 컴포넌트가 이러한 값을 공유하도록 할 수 있습니다.
출처 - https://ko.reactjs.org/docs/context.html
npx create-react-app react-context-example
import React from 'react';
const PersonContext = React.createContext();
export default PersonContext;
// index.js
const persons = [
{ id: 0, name: 'Mark', age: 38 },
{ id: 1, name: 'Hanna', age: 27 },
];
ReactDOM.render(
<PersonContext.Provider value={persons}>
<App />
</PersonContext.Provider>
, document.getElementById('root'));
import PersonContext from './contexts/PersonContext';
const persons = [
{ id: 0, name: 'Mark', age: 39},
{ id: 1, name: 'Hanna', age: 28}
];
ReactDOM.render(
<React.StrictMode>
<PersonContext.Provider value={persons}>
<App />
</PersonContext.Provider>
</React.StrictMode>
document.getElementById('root')
);
import { useContext } from 'react';
import PersonContext from '../contexts/PersonContext';
export default function Example1() {
return(
<PersonContext.Consumer>
{ (persons) => (
<ul>
{persons.map( (person) => (
<li>{person.name}</li>
)
)}
</ul>
)}
</PersonContext.Consumer>
);
}
import Example1 from './components/Example1';
function App() {
return(
<div className="App">
<Example1 />
</div>
);
}
export default App;
여러 개 지정되지 않아 선호되지는 않음
import React from 'react';
export default class Example2 extends React.Component {
// static contextType = PersonContext;
render() {
const persons = this.context;
return(
<ul>
{persons.map( (person) => (
<li>{person.name}</li>
)
)}
</ul>
);
}
}
Example2.contextType = PersonContext; // static 대신
import Example2 from './components/Example2';
function App() {
return(
<div className="App">
<Example2 />
</div>
);
}
export default App;
★ 가장 많이 쓰이는 방식
★ 요즘은 대부분 hook으로 개발하기 때문에 꼭 알아둬야 하는 중요한 개념
import { useContext } from 'react';
import PersonContext from '../contexts/PersonContext';
export default function Example3() {
const persons = useContext(PersonContext);
return(
<ul>
{persons.map( (person) => (
<li>{person.name}</li>
)
)}
</ul>
);
}
import Example3 from './components/Example3';
function App() {
return(
<div className="App">
<Example3 />
</div>
);
}
export default App;
https://dev-yakuza.posstree.com/ko/react/context-api/
https://hyeok999.github.io/2020/02/14/ReactStudy-05/#a8
https://goforit.tistory.com/132?category=953050