hooks 방식의 컴포넌트 생명 주기

# 맨 아래의 전체 소스 코드가 있습니다.


# 클래식 방식의 컴포넌트 주기 : minaminaworld.tistory.com/196

 

[react - 기초] class 방식의 컴포넌트 생명 주기

class 방식의 컴포넌트 생명 주기 # 맨 아래의 전체 소스 코드가 있습니다.  # 리액트 공식문서 : https://ko.reactjs.org/docs/react-component.html React.Component – React A JavaScript library for b..

minaminaworld.tistory.com


# Hooks 방식의 경우, Class와는 다르게 componentDidMount, componentDidUpdate, componentWillUnmount 처럼 명확하게 나누어져 있지 않음. 그러나 useEffect만으로 구현이 가능함.

 // class 방식의 componentDidMout
  useEffect(() => {
    console.log('componentDidMout -------------------------');
    console.log('component가 실행될 때만 동작합니다.');
    console.log(' ------------------------- componentDidMout');
  }, []);

  // class 방식의 componentDidUpdate 동작
  // 배열 요소의 변경이 있을 때만 동작함
  useEffect(() => {
    console.log('componentDidUpdate -------------------------');
    // 값의 변화에 대응
    if (num) {
      console.log('num=', num);
    }
    console.log('-------------------------componentDidUpdate ');
  }, [num]);

  // class 방식의 componentDidUpdate 동작
  // 배열 요소의 변경이 있을 때만 동작함
  useEffect(() => {
    return () => {
      console.log('componentWillUnmount-------------------------');
      console.log('componentWillUnmount 동작함');
      console.log('-------------------------componentWillUnmount ');
    };
  }, [num]);

 

 

# 컴포넌트 시작 시 useEffect 실행.

# 값 변화로 인한 useEffect 실행.

# 값 변화로 인한 DOM의 종료로 인한 useEffect 실행.

 

 


# 전체소스코드

import React, { memo, useEffect, useState } from "react";

const useEffectTest = () => {
  const [title, setTitle] = useState("ComponentMountTest");
  const [num, setNum] = useState(0);

  // class 방식의 componentDidMout
  useEffect(() => {
    console.log('componentDidMout -------------------------');
    console.log('component가 실행될 때만 동작합니다.');
    console.log(' ------------------------- componentDidMout');
  }, []);

  // class 방식의 componentDidUpdate 동작
  // 배열 요소의 변경이 있을 때만 동작함
  useEffect(() => {
    console.log('componentDidUpdate -------------------------');
    // 값의 변화에 대응
    if (num) {
      console.log('num=', num);
    }
    console.log('-------------------------componentDidUpdate ');
  }, [num]);

  // class 방식의 componentDidUpdate 동작
  // 배열 요소의 변경이 있을 때만 동작함
  useEffect(() => {
    return () => {
      console.log('componentWillUnmount-------------------------');
      console.log('componentWillUnmount 동작함');
      console.log('-------------------------componentWillUnmount ');
    };
  }, [num]);

  const onIncreseNum = () => {
    console.log("onIncreseNum");
    setNum((prevNum) => {
      return prevNum + 1;
    });
  };

  const onDecreseNum = (sign) => (e) => {
    console.log("onDecreseNum");
    console.log(`sign ${sign}`);
    setNum((prevNum) => {
      return prevNum - 1;
    });
  };

  return (
    <>
      <h1>{title}</h1>
      <h1>{num}</h1>
      <button onClick={onIncreseNum}>+</button>
      <button onClick={onDecreseNum('-')}>-</button>
    </>
  );
};

export default useEffectTest;
블로그 이미지

미나미나미

,

# react state에 관한 설명

ko.reactjs.org/docs/state-and-lifecycle.html

 

State and Lifecycle – React

A JavaScript library for building user interfaces

ko.reactjs.org


- react에서 state을 사용한 데이터 관리 


- 폴더 

 


1.  class 방식

// class 방식일 경우 
import React, { Component, PureComponent } from 'react';

class StateTest extends Component {
    state = {
        text: 'state에서 text 알아보기',
        num: 0
    };

    componentDidMount() {
        console.log('=============================componentDidMount');
    }

    // 리렌더링할 요소를 지정
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        return true;
    }

    // 리렌더링의 경우
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log('=============================componentDidUpdate');
    }

    // 컴포넌트가 제거되기 전 , 비동기 요청 정리를 많이함
    componentWillUnmount() {
        console.log('=============================componentWillUnmount');
    }

    // 값에 변화주기 
    onNumBtn = (sign) => (e) => {
        if (sign === '+') {
            // setState에서는 값을 직접적으로 참조가 불가능함으로 함수로 리턴 형식으로 함.
            this.setState((pre) => {
                console.log(pre);
                return {
                    text: '증감',
                    num: pre.num + 1
                }
            });
        } else {
            this.setState((pre) => {
                console.log(pre);
                return {
                    text: '감소',
                    num: pre.num - 1
                }
            });
        }
    };

    render() {
        // state 값 가져오기
        const { text, num } = this.state;
        return (
            <>
                <h2 id='test'>{text}</h2>
                <h2 id='num'>{num}</h2>
                <div>
                    <button onClick={this.onNumBtn('+')}>+</button>
                    <button onClick={this.onNumBtn('-')}>-</button>
                </div>

            </>
        );
    };
}
export default StateTest;

 

 

2.  Hooks 방식

// class 방식일 경우 
// import React, { Component, PureComponent } from 'react';
import React, { memo, useEffect, useRef, useState } from 'react';

const StateTest = memo(() => {
    const [text, setText] = useState('Hooks Text Display');
    const [num, setNum] = useState(0);
    const [inputVal, setInputVal] = useState('input text');
    const input = useRef();

    useEffect(() => {
        console.log('num = ', num);
        console.log('text = ', text);
        input.current.focus();
    }, [text, num, input]);

    const onNumBtn = (sign) => (e) => {
        if (sign === '+') {
            setText('증감');
            setNum((pre) => {
                return pre + 1;
            });
        } else {
            setText('감소');
            setNum((pre) => {
                return pre - 1;
            });
        }
    };

    const onInputValChange = (e) => {
        setInputVal(e.target.value);
    };

    return (
        <>
            <h2 id='test'>{text}</h2>
            <h2 id='num'>{num}</h2>
            <div>
                <button onClick={onNumBtn('+')}>+</button>
                <button onClick={onNumBtn('-')}>-</button>
            </div>
            <input type='text' value={inputVal} onChange={onInputValChange} ref={input}></input>
            <h1>{inputVal}</h1>
        </>
    );
});

export default StateTest;

3. index.jsx

// import 방법과 const 방법 . 
// 한방향으로 지정해서 프로젝트 이끌어가여함 안그러면 충돌남.
// const React = require('react');
import React from 'react';

// # https://ko.reactjs.org/docs/react-dom.html
// react-dom package는 앱의 최상위 레벨에서 사용할 수 있는 DOM에 특화된 메서드와 필요한 경우 React 모델 외부로 나갈 수 있는 해결책을 제공
// render(), hydrate(), unmountComponentAtNode(), findDOMNode(), createPortal()
// const ReactDom = require('react-dom');
import ReactDom from 'react-dom';

// # https://gist.github.com/velopert/21896de87566628b38b7ecb95973a7b3
// 코드가 변경되었을 때 페이지를 새로고침하지 않고 바뀐 부분만 빠르게 교체해주는 라이브러리
// const { hot } = require('react-hot-loader/root');
import { hot } from 'react-hot-loader/root';

// 불러올 컴포넌트의 이름
// import ResponseCheck from "./ResponseCheck";
// import RSP from "./RSP";
import StateTest from './component/StateTest';
const Hot = hot(StateTest);

ReactDom.render(<Hot />, document.querySelector('#root'));


 

 

4. webpack.config.js

const path = require('path');
const webpack = require('webpack');
// process.env.NODE_ENV = 'production';

module.exports = {
    // 프로젝트 이름 , 카멜 케이스는 안됨, 두 단어 이상을 사용한 프로젝트 이름 
    name: 'state-test', 
    mode: 'development', // 실서비스 : productuon
    // mode: 'productuon', // 실서비스 : productuon
    devtool: 'eval', // 빠르게
    resolve: {
        // 파일 형식 
        extensions: ['.js', '.jsx']
    },
    entry: {
        app: ['./index']
    }, // 입력
    module: {
        rules: [{
            test: /\.jsx?/,
            loader: 'babel-loader',
            options: {
                presets: [
                    ['@babel/preset-env', {
                        targets: {
                            browsers: ['> 5% in KR']
                        },
                        debug: true,
                    }],
                    '@babel/preset-react'],
                plugins: [
                    '@babel/plugin-syntax-class-properties',
                    "transform-class-properties",
                    'react-hot-loader/babel'
                ]
            }
        }]
    },
    plugins: [
        new webpack.LoaderOptionsPlugin({ debug: true }),
    ],
    output: {
        // webpack-dev-server에서 hot 로드 되기 위해서 위치 지정, 없을 경우 html에서 ./dist/app.js를 app.js로 변경해야함
        publicPath: '/dist/',
        path: path.join(__dirname, 'dist'),
        filename: 'app.js'
    }, // 출력
    devServer: {
        // contentBase: path.join(__dirname, "dist"),
        inline: true,
        hot: true,
        port: 9000,
        hot:true
    },

}

5. package.json

{
  "name": "number-baseball",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^16.14.0",
    "react-dom": "^16.14.0"
  },
  "devDependencies": {
    "@babel/plugin-syntax-class-properties": "^7.12.1",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "babel-loader": "^8.1.0",
    "react-hot-loader": "^4.12.21",
    "webpack": "^4.44.2",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  }
}

 

블로그 이미지

미나미나미

,