728x90

리액트는 컴포넌트 기반의 View 중심으로 라이브러리이다. 그러다보니 각각의 컴포넌트에는 라이프사이클 , 컴포넌트의 수명 주기가 존재한다. 컴포넌트의 수명은 보통 페이지에서 렌더링되기 전인 준비 과정에서 시작하여 페이지에서 사라질 끝이난다.

 

라이플사이클 과정: 

 

컴포넌트가 생겼다가 사라진다. 생겼다가 사라지는 동안에 어떤 작업을 할 것인데, 

클래스인 경우, constructor -> render -> ref -> componentDidMount -> (setState/props 바뀔때) ->  shouldComponentUpdate(true)-> render -> componentDidUpdate -> 부모가 나를 없앴을 때 -> componentWillUnmount  -> 소멸 

 

 (클래스 설명) : constructor(state, 메서드 ) 실행되고 처음으로 render 실행된다. 다음 ref 설정해주는 부분이 실행된다. 그리고 componentDidMount 실행되고 setState Props 바뀔 componentDidUpdate 실행되고 부모가 나를 없앴을 componentWillUnmount 실행되고 소멸된다.

 


componentDidMount에서 비동기 요청을 많이 한다. 예를 들어 setInterval 있다. 그리고 componentWillUnmount에서는 비동기 요청을 정리한다. 

 

 

setInterval 일정 시간마다 반복 작업을 해주는 것임을 우리는 알고 있다. 그러면 렌더링 후에 componentDidMount 실행되어서 일정시간 간격으로 하는(setInterval) 반복 작업을 계속 해준다. 문제는 컴포넌트가 사라져도 setInterval 취소 해주지 않는다. 그러면 웹사이트를 까지 해당 컴포넌트가 사라졌다해도 계속 setInterval 실행되고 있다.
여기서 문제가 발생할 있다. 만약 RSP 라는 컴포넌트가 있고 렌더링 되고 setInterval 1초마다 실행된다. 그리고 RSP컴포넌트가 사라졌다가, 어떤 계기로 RSP 컴포넌트가 화면에 붙었다가 사라지면, 기존에 실행되고 있었던 setInterval에다가setInterval 하나 추가 되어서 두개가 같이 돌아가게 된다. 작업이 반복되면 setInterval 계속 중첩이된다. 이러한 비동기 함수들이 메모리를 계속 차지하기 때문에 flooding 생긴다. 그래서 완료되지 않는 비동기 요청은 componentWillUnmount에서 처리를 해줘야한다.

 

그래서 취소를 해주어야한다.

이런 식으로 해준다.


render가 처음 실행되고 성공적으로 실행됐다면 componentDidMount가 실행된다. 그 다음 setState로 인해서 리 렌더링이 일어날 때는 componentDidMount가 실행되지 않는다.

 

그리고 컴포넌트가 제거되기 직전에는 componentWillUnmount 가 실행된다. 부모가 나(컴포넌트)를 없앴을 때 실행된다.

 

render에서 setState를 사용하면 무한하게 렌더링 되어서 문제가 생긴다. 그러면 render에 setState를 사용해야 하는 상황에는 어디에다 써야할까? componentDidMount에 사용해야한다. 

 

 

componentDidUpdate setState 하던 Props 바뀌었다하면 render 부분이 다시 실행되잖아요. 리렌더링 후에는 componentDidUpdate 실행된다.

'프레임워크 > React' 카테고리의 다른 글

[React] useMemo  (0) 2021.07.29
[React] useCallback  (0) 2021.07.29
[React] useReducer  (0) 2021.07.29
[React] contextAPI  (0) 2021.07.29
[React] PureComponent와 shouldComponentUpdate  (0) 2021.07.23
728x90

hooks의 특성이 컴포넌트 전체가 계속 다시 실행되는 것이다. 만약 매번 다시 실행되는 것이 만약 10초가 걸리는 함수가 있다면 렌더링 할 때 마다 10초가 걸리기 때문에 문제가 발생한다. 해결법은 캐싱 하는 것이다. 이 때 다시 실행되지 않고 기억할 수 있게 useMemo가 쓰인다. (함수를 실행한 결과값을 저장해 두려면 useMemo이다)

 

※ useEffect, useMemo, useCallback은 두번째 인자가 있다.

 

const ____ = useMemo( ( ) => getWinNumbers(), []); 두번째 인자가 바뀌지 않는한 함수가 다시 실행되지 않는다.

다시 말해 두 번째 인자인 [ ]가 바뀌기 전 까지 함수의 결과값을 기억한다.

 

이렇게 되면 hooks가 getWinNumbers() 함수의 리턴값을 기억할 것이다. 이렇게 하지 않으면 getWinNumbers()같은 함수는( 반복문이 돌 때 마다 or 렌더링이 될 때 마다 )계속 실행 될 것이다.

 

 

useMemo: 복잡한 함수 결과값을 기억

useCallback: 함수 자체를 기억

useRef: 일반 값을 기억

 

 

여기서 tip:

함수 안에 console.log 하나씩 찍어두고 내가 진짜 필요할 돌아가는게 맞는지 확인해주기!

'프레임워크 > React' 카테고리의 다른 글

[React] 라이프사이클(life cycle)  (0) 2021.07.29
[React] useCallback  (0) 2021.07.29
[React] useReducer  (0) 2021.07.29
[React] contextAPI  (0) 2021.07.29
[React] PureComponent와 shouldComponentUpdate  (0) 2021.07.23
728x90

useEffect, useCallback, useMemo 같듯이


const _____ = useCallback(() => {

 

}, [ ]);


-두 번째 인자인 [ ]가 바뀌면 새로 실행된다.

-두 번째 인자인 [ ]가 바뀌기 전 까지 함수 자체를 기억한다. 

 


문제점

 

const onClickRedo = useCallback(() => {

    console.log(winNumbers);

},[]);

 

이렇게 하면 winNumbers에서 받아온 값들을 계속 기억한다. 

 

반면 계속 새로운 값들로 업데이트 하려면

 

const onClickRedo = useCallback(() => {

    console.log(winNumbers);

},[winNumbers]);

 

이렇게 해야한다.

 

어떨 함수를 실행할지 정하는곳이 “ [ ] “ 이다.


자식 컴포넌트로 함수를 넘길 때 useCallback을 꼭 해줘야한다. useCallback이 없으면 매번 새로운 함수가 생성된다. 그러면 자식 컴포넌트는 부모로 받은 props가 바뀌었다고 인식하여 매번 새로 렌더링을 해버리기 때문이다.(함수 자체는 사실상 바뀐게 없는데 이렇게 되면 매우 비효율적이다)

그러므로 결론은 자식 컴포넌트에 props 함수를 넘길때는 자식이 헷갈리지 않게 useCallback 해주어서 자식이 쓸때없이 렌더링이 되지 않고 부모로 부터 받은 함수가 같음을 알아차리게 해줘야한다.

'프레임워크 > React' 카테고리의 다른 글

[React] 라이프사이클(life cycle)  (0) 2021.07.29
[React] useMemo  (0) 2021.07.29
[React] useReducer  (0) 2021.07.29
[React] contextAPI  (0) 2021.07.29
[React] PureComponent와 shouldComponentUpdate  (0) 2021.07.23
728x90

state개수를 줄여준다. 

state 많아지면 state, setState 쌍들이 점점 늘어나기 때문에 관리하기 힘들고, 다른 컴포넌트에 넘겨줄게 너무 많아지기 때문에 useReducer 사용해서 하나의 state 하나의 setState 통일할 있다. 이것이 useReducer 사용하는 목적이다.

 

 

const initialState = {

	state1: ‘0’,

	state2: ‘0’,

	state3: ‘0’,

	state4: ‘0’,

};





const UseReducerTest = () => {

	const [state, dispatch] = useReducer(reducer, initialState);



	// const [state1, setState1] = useState('');

	// const [state2, setState2] = useState('');

	// const [state3, setState3] = useState('');

	// const [state4, setState4] = useState('');



}

 

state(initialState)가 있고 그 안에 객체 형식으로 데이터를 둔다고 가정하자. 이 state는 아무도 직접 수정할 수 없다. 클릭같은 것들을 담당하고 있는 이벤트들이 웹서비스로 부터 계속 발생하는 영역이다.

state 아무도 수정할 없고 이것을 수정하고 싶으면 action 만들고 이것을 실행(dispatch) 해야한다. action 어떻게 처리할지는 reducer에서 관리한다

 

요약: state 있고 state 직접 건들수가 없고 바꾸고 싶으면 이벤트가 실행될 action dispatch해서 state 바꿔야한다. state 어떻게 바꿔야할지는 reducer 기록해야한다.

 

 

reducer 메커니즘

'프레임워크 > React' 카테고리의 다른 글

[React] useMemo  (0) 2021.07.29
[React] useCallback  (0) 2021.07.29
[React] contextAPI  (0) 2021.07.29
[React] PureComponent와 shouldComponentUpdate  (0) 2021.07.23
[React] 배열  (0) 2021.07.22
728x90

 

contextAPI 부모와 자식간에 다층관계가 되면 props 물려주는게 힘든점을 개선해준다. contextAPI에서 접근할 있는 데이터가 있는데, 여기에 접근하고 싶은 컴포넌트들을 contextAPI 제공하는 Provider 묶어줘야한다.(아래 참고)

 

Main.jsx
import React, {createContext} from 'react';

export const TableContext = createContext({
    tableData: [],
    dispatch: () => {},
});

여기에서는 이렇게 전달할 데이터들의 모양만 맞춰주면 된다.

 

…
<TableContext.Provider value={{ tableData: state.tableData, dispatch }}>
    <Form />
    <div>{state.timer}</div>
    <Table />
    <div>{state.result}</div>
</TableContext.Provider>

데이터들은 value에 넣는다. 이 데이터들은 자식 컴포넌트들에게 바로 전달해줄 데이터들이다. 그러면 자식 컴포는트들에서 접근 가능한 데이터들이 된다. 

 

그리고 자식 컴포넌트에서 contextAPI 연결 시키는 방법은

Form.jsx
import React, { useContext } from 'react';

const Form = () => {
	const value = useContext(TableContext);
…
}

이런식으로 하면 된다. 그러면 가져올 때는

value.dispatch, value.tableData 이렇게 가져올 수 있다. 또한

 

{ tableData, dispatch } = useContext(TableContext);

 

이런식으로 구조분해해서 사용 가능하다.

'프레임워크 > React' 카테고리의 다른 글

[React] useCallback  (0) 2021.07.29
[React] useReducer  (0) 2021.07.29
[React] PureComponent와 shouldComponentUpdate  (0) 2021.07.23
[React] 배열  (0) 2021.07.22
[React] 화살표 함수를 안쓸 때  (0) 2021.07.22
728x90

하나가 바뀌면 화면 전체가 리 렌더링되는 현상을 방지할 수 있다.

 

shouldComponentUpdate(nextProps, nextState, nextContext) {

    if (this.state.counter !== nextState.counter) {  

        return true;                                

    }

    return false;

}

 

this.state.counter 현재의 카운터고 nextState.counter 미래에 바뀌는 카운터이다.

그래서 만약 state 바뀌면 렌더링을 해라는 뜻이다. 이렇게 해줘야 쓸대없는 렌더링이 없어진다.

 


더 혁신적인 방법 - PureComponent

 

import React, {PureComponent} from "react";

class Test extends PureComponent {
	...
 }

PureComponent가 shouldComponentUpdate를 알아서 구현된 것이다.

'프레임워크 > React' 카테고리의 다른 글

[React] useReducer  (0) 2021.07.29
[React] contextAPI  (0) 2021.07.29
[React] 배열  (0) 2021.07.22
[React] 화살표 함수를 안쓸 때  (0) 2021.07.22
[React] map 다른 파일로 빼기  (0) 2021.07.22
728x90

밑에 처럼 기존 배열에 push를 하면 배열이 하나만 있는 것이다. 이러면 리액트가 뭐가 바뀌었는지 감지를 못한다. 

const array = [];

array.push(1);

그래서 

const array2 = […array, 2]

기존 배열을 복사 해놓고 새로운 값을 넣어주는 형태이다.

리액트가 이것을 감지할 있는 이유가 기존 배열이랑 새로운 배열이랑 다르기 때문이다.

array === array2

=> false

리액트가 렌더링하는 기준이 예전 state 현재 state 다르면 렌더링을 하는 것이다. 참조가 바뀌어야한다.

const array = [];

array.push(1);

arr === arr
=> true

이러면 리액트가 바뀐 것이 없다고 판단하여 렌더링을 하지 않는다. 그래서 리액트를 push 하면 안된다.

'프레임워크 > React' 카테고리의 다른 글

[React] contextAPI  (0) 2021.07.29
[React] PureComponent와 shouldComponentUpdate  (0) 2021.07.23
[React] 화살표 함수를 안쓸 때  (0) 2021.07.22
[React] map 다른 파일로 빼기  (0) 2021.07.22
[React] Map 사용법  (0) 2021.07.22
728x90

  

onSubmitForm this 출력해보면

 

 

리액트 내부가 나온다. 만약this.onChangeInput = this.onChangeInput.bind(this); “ 주석처리 해보면

 

this가 undefined가 되는걸 볼 수 있다.

 

화살표 함수가 bind(this)를 자동으로 해주는 기능을 한다.

 

onSubmitForm = (e) => {

       console.log(this.state.value);

}

 


최종적으로

 

화살표 함수를 사용하면 이렇게 편리하게 사용할 있다.

'프레임워크 > React' 카테고리의 다른 글

[React] PureComponent와 shouldComponentUpdate  (0) 2021.07.23
[React] 배열  (0) 2021.07.22
[React] map 다른 파일로 빼기  (0) 2021.07.22
[React] Map 사용법  (0) 2021.07.22
[React] webpack 설정들의 의미  (0) 2021.07.09
728x90

 

Main.jsx
Main.jsx

위와 같은 코드가 밑에와 같은 결과가 나온다. 너무 길어지니깐 다른 파일에 따로 <li> 부분을 떼어낼 있다.

 

위 코드의 결과

  • 다른 파일로 빼는 이유는 가독성적인 면도 있지만 반복문에서 성능 문제가 발생하기 때문에 성능적인 것도 있음

다음과 같은 방법으로.

 

Try.jsx


Main.jsx
Main.jsx

그러나 위와 같이 하면 v와 index가 Try에 전달이 안된다. 전달을 하는 것이 바로 Props 이다.

       💡 html에서는 attribute라고 부르는데 React에서는 Props라고 부른다.

       💡 Props: 부모한테 받을 때 사용한다.

 

밑에와같이 하면 Props 전달이 된다.

 

Try.jsx
Main.jsx

 

'프레임워크 > React' 카테고리의 다른 글

[React] 배열  (0) 2021.07.22
[React] 화살표 함수를 안쓸 때  (0) 2021.07.22
[React] Map 사용법  (0) 2021.07.22
[React] webpack 설정들의 의미  (0) 2021.07.09
[React] 라우트 파라메터  (0) 2021.06.30
728x90

 

결과:


응용

 

위에를 반복문으로 하기에는 두 가지 방법을 생각해볼 수 있다. 1) 2차원배열로 하기. 2) 객채로하기


1. 2차원 배열

 

2. 객체로

객체로 하는 반복문을

가독성 + 성능을 잡을 있는 것이 Props 이다.


map을 돌릴 때 추가해줘야 할 것 이 key 이다. 이게 없으면 위와같은 에러 메시지가 발생한다.

  • 이 key는 리액트가 나중에 성능을 최적화 할 때 사용하는 것이다.
  • 리액트는 key를 보고 같은 컴포넌트인지 아닌지 판단을 한다.
  • 리액트에서 key를 기준으로 엘리먼트를 추가하거나 수정 삭제 판단하기 때문에 배열의 순서가 바뀌면 문제가 생긴다.

key 고유한 값을 찾아야한다. 밑에처럼.

 

 

index를 key에 넣으면 나중에 성능 최적화할 때 문제가 생기기 때문에 안된다. key의 역할이 성능 최적화인데 역할이 무의미 해진다.

 

가독성 있게 밑에와 같이 배열을 따로 빼놓아도 된다.

 

'프레임워크 > React' 카테고리의 다른 글

[React] 화살표 함수를 안쓸 때  (0) 2021.07.22
[React] map 다른 파일로 빼기  (0) 2021.07.22
[React] webpack 설정들의 의미  (0) 2021.07.09
[React] 라우트 파라메터  (0) 2021.06.30
[React] gravatar  (0) 2021.06.28

+ Recent posts