Main Course 주특기 2강 - React
주특기 2강!
- 컴포넌트의 state를 관리할 수 있다.
- 컴포넌트의 라이프 사이클을 이해한다.
- 오픈소스 패키지를 찾아서 설치할 수 있다.
- event listener를 구독할 수 있다.
- React hook 중 useState(), useEffect()를 사용할 수 있다.
scss
// Nesting이 가능하다.
// div 아래에 p, img 태그 스타일을 줄 때, 각각 다른 블럭을 만들어 쓸 필요가 없어요!
// 축약형으로 묶을 수 있어요. → xxx-yyy 식일 때, 앞에 xxx가 같은 친구끼리 묶어 쓸 수 있어요!
div {
p {
color: #888888;
font: {
family:sans-serif;
size: 14px;
}
}
img {
width: 400px;
}
}
// 상위 요소 이어쓰기는 "&"로! 클래스명 등, 글자도 이어쓸 수 있어요.
div {
background-color: green
&:hover { background-color: blue }
}
.div {
background-color: green
&_blue { background-color: blue }
}
// 문자열을 치환할 수 있습니다! (즉, 변수를 쓸 수 있어요!)
$defaultSize: 20px;
$className: blue;
p{
font-size: #{$defaultSize};
&.#{$className} {color: #{$className}}
}
styled-components
yarn add styled-components
패키지 설치하기
function App() {
return (
<div className="App">
{/* props로 bgColor를 줘볼까요! */}
<MyStyled bgColor를={"red"}>hello React!</MyStyled>
</div>
);
}
// scss처럼 자기 자신을 지칭할 때 &를 쓸 수 있습니다!
// props 주는 방법! 이제 알고 있죠?
// 백틱을 사용함
const MyStyled = styled.div`
width: 50vw;
min-height: 150px;
padding: 10px;
border-radius: 15px;
color: #fff;
&:hover{
background-color: #ddd;
}
background-color: ${(props) => (props.bgColor ? "red" : "purple")};
`;
Life Cycle
- 컴포넌트는 생성되고 → 수정(업데이트)되고 → 사라집니다.
- 생성은 처음으로 컴포넌트를 불러오는 단계입니다.
- 수정(업데이트)는 사용자의 행동(클릭, 데이터 입력 등)으로 데이터가 바뀌거나, 부모 컴포넌트가 렌더링할 때 업데이트 됩니다. 아래의 경우죠!
- props가 바뀔 때
- state가 바뀔 때
- 부모 컴포넌트가 업데이트 되었을 때(=리렌더링했을 때)
- 또는, 강제로 업데이트 했을 경우! (forceUpdate()를 통해 강제로 컴포넌트를 업데이트할 수 있습니다.)
- 제거는 페이지를 이동하거나, 사용자의 행동(삭제 버튼 클릭 등)으로 인해 컴포넌트가 화면에서 사라지는 단계입니다.
-
constructor()
생성자 함수라고도 부릅니다. 컴포넌트가 생성되면 가장 처음 호출되는 친구죠! -
render()
컴포넌트의 모양을 정의하는 친구입니다!
여기에서도 state, props에 접근해서 데이터를 보여줄 수 있어요.
리액트 요소를 return에 넣어 반환해줬던 거 기억하시죠?
render() 안에 들어갈 내용은 컴포넌트의 모양에만 관여하는 것이 가장 좋습니다.
즉, state나, props를 건드려 데이터를 수정하려고 하면 안됩니다! -
componentDidMount()
컴포넌트가 화면에 나타나는 것을 마운트(Mount)한다고 표현합니다. didMount()는 마운트가 완료 되었다는 소리겠죠?
이 함수는 첫번째 렌더링을 마친 후에만 딱 한 번 실행됩니다. 컴포넌트가 리렌더링할 때는 실행되지 않아요.
보통은 이 안에서 ajax 요청, 이벤트 등록, 함수 호출 등 작업을 처리합니다.
또, 이미 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 됩니다! -
componentDidUpdate(prevProps, prevState, snapshot)
DidMount()가 첫 렌더링 후에 호출 되는 함수라면, DidUpdate()는 리렌더링을 완료한 후 실행되는 함수입니다.
이 함수에 중요한 파라미터가 2개 있는데, prevProps와 prevState입니다. 각각 업데이트 되기 전 props, state예요. 이전 데이터와 비교할 일이 있다면 가져다 쓰도록 합시다.
DidUpdate()가 실행될 때도 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 됩니다! -
componentWillUnmount()
컴포넌트가 DOM에서 제거 될 때 실행하는 함수입니다.
만약 우리가 스크롤 위치를 추적 중이거나, 어떤 이벤트 리스너를 등록했다면 여기에서 꼭꼭 해제를 해줘야 합니다.
컴포넌트 없이 이벤트만 남겨둘 순 없잖아요!
Ref
특정 요소에 접근하는 방법으로 사용됨.
클래스형 컴포넌트에서는 React.createRef()로 호출하고,
함수형 컴포넌트에서는 React.useRef()로 호출한다.
createRef
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
};
// ref는 이렇게 선언합니다!
this.text = React.createRef(); // text는 그냥 변수명임.
}
componentDidMount(){
console.log(this.text);
console.log(this.text.current); // current를 써야 노드 접근이 됨.
}
render() {
return (
...
<div>
<input type="text" ref={this.text}/>
</div>
useRef
const nameInput = useRef();
console.log(nameInput.current)
<input ref={nameInput}/>
State 관리
setState
import React from 'react';
class App extends React.Component {
constructor(props){
super(props);
this.state = {
count: 3,
};
}
addNemo = () => {
this.setState({count: this.state.count + 1}) // key는 count, value는 this.state.count
}
removeNemo = () => {
if (this.state.count > 0) {
this.setState({count: this.state.count - 1}) // 계속 줄다보면 this.state.count가 0 이하가 되는데 이때는 UX를 고려하여 alert을 날려주자.
} else {
alert('더 이상은 naver...!')
}
}
render() {
const nemo_count = Array.from({length: this.state.count}, (item, index) => index)
return (
<div className="App">
{nemo_count.map((num, index) => { // 돔 구조 안에서 map을 이용한 반복문을 사용하기 위해 {} bracket으로 감싸주었음.
return (
<div key={index} style={{
width: '150px',
height: '150px',
backgroundColor: '#eee',
margin: '10px'
}}>
nemo
</div>
)
})}
<button onClick={this.addNemo}>+</button>
<button onClick={this.removeNemo}>-</button>
</div>
);
}
}
export default App;
useState
import React from "react";
const Nemo = (props) => {
const [count, setCount] = React.useState(3); // 함수형 컴포넌트에서 state 값을 변경하는 법, React.useState()를 사용해서 위에서 import 하지 않고도 사용할 수 있었음.
const nemo_count = Array.from({length: count}, (item, index) => index) // 함수형 컴포넌트에서는 this를 사용하지 않음.
const addNemo = () => {
setCount(count + 1); // 매개변수의 값을 count에 할당해주는것임.
}
const removeNemo = () => {
setCount(count > 0 ? count - 1 : 0); // 삼항 조건식
}
return (
<div className="App">
{nemo_count.map((num, index) => { // 돔 구조 안에서 map을 이용한 반복문을 사용하기 위해 {} bracket으로 감싸주었음.
return (
<div key={index} style={{
width: '150px',
height: '150px',
backgroundColor: '#eee',
margin: '10px'
}}>
nemo
</div>
)
})}
<button onClick={addNemo}>+</button>
<button onClick={removeNemo}>-</button>
</div>
);
};
export default Nemo;
Event Listener
import React from 'react';
import Nemo from './Nemo';
class App extends React.Component {
constructor(props) {
super(props)
this.div = React.createRef(); // ref로 이벤트 리스너 추가할 노드 잡기.
}
hoverEvent = (e) => { // 매개변수에 e(관습적)로 이벤트를 받아옴.
e.target.style.backgroundColor = "red"
// 여기서 e는 마우스 오버, e.target은 this.div.current 노드가 됨.
}
componentDidMount() { // 마운트가 완료되고 불러와야 dom에 문제없이 접근할 수 있음.
this.div.current.addEventListener("mouseover", this.hoverEvent)
}
componentWillUnmount() { // 이벤트 리스너는 반드시! 언마운트 될때를 고려해서 제거해줘야 함.
this.div.current.removeEventListener("mouseover", this.hoverEvent) // 이때 사용하는 메서드는 removeEventListener
}
render() {
return (
<div className="App" ref={this.div}>
<Nemo ></Nemo>
</div>
);
}
}
export default App;
useEffect
함수형 컴포넌트에서 라이프 사이클에 따라 동작을 추가하는 방법.
최초 렌더링 시에는 어떤 경우에든 반드시! useEffect의 콜백 함수가 한번은 동작함.
// dependency가 없는 방법. ->
// 렌더링 직후, 어떤 값이든 변화(부모 컴포넌트가 변화해도)만 생기면 콜백 함수가 실행됨.
useEffect(() => {});
// dependency에 빈 배열을 넣는 방법. -> 렌더링 직후 한 번만 콜백 함수 실행됨.
useEffect(() => {}, []);
// dependency에 객체나 변수를 넣는 방법. -> 렌더링 직후, 배열 내 변수가 변할때마다 콜백 함수가 실행됨.
useEffect(() => {}, [변수 혹은 오브젝트]);
// return을 주면 언마운트 시에 동작시킬 함수를 넣을 수 있음.
// 이를 cleanup 함수라고 표현함.
useEffect(() => {
console.log("표시");
return () => console.log("비표시");
}, []);
더 알아보면 좋을 내용
-
useCallback과 React.Memo
렌더링 최적화와 관련된 내용 -
react-tinder-card
스와이프 기능과 관련된 내용
Author And Source
이 문제에 관하여(Main Course 주특기 2강 - React), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@uvula6921/Main-Course-2강-주특기-React저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)