[React] 라이프 사이클 메서드(Life Cycle Method)

2022. 6. 21. 17:06·Stack/React

라이프 사이클 - 수명주기

컴포넌트의 수명은 페이지에 랜더링 되기 전인 준비 과정 -> 페이지에서 사라질 때 끝남

 

라이프 사이클 메서드 - 클래스 컴포넌트

함수형 컴포넌트 Hooks 기능을 사용하여 처리

 

Hooks

1) useState

2) useRef

3) useEffect

 

마운트, 업데이트, 언마운트

1) 마운트: 페이지에 컴포넌트가 나타남

constructor: 컴포넌트 새로 만들 때마다 호출되는 클래자 생성자 메서드 ->

getDerivedStateFromProps: props에 있는 값은 state에 넣을 때 사용되는 메서드 ->

render: 우리가 준비한 UI를 랜더링하는 메서드 ->

componentDidMount: 컴포넌트 웹 브라우저상에 나타난 후 호출되는 메서드

 

2) 업데이트: 컴포넌트 정보를 업데이트 - 리렌더링

① props가 변경될 때

② state가 변경될 때

③ 부모 컴포넌트가 리렌더링 될 때

④ this.forceUpdate를 이용하여 강제로 렌더링을 트리거할 때

업데이트 발생

 

getDerivedStateFromProps: props에 있는 값은 state에 넣을 때 사용되는 메서드 ->

shouldComponentUpdate: 컴포넌트가 리렌더링 해야할지 말아야할지를 결정하는 메서드->

true 반환시 render 호출, false 반환시 여기에서 작업 취소

render ->

getSnapshotBeforeUpdate: 컴포넌트 변화를 DOM에 반영하기 직전에 호출하는 메서드 ->

componentDidupdate -> 컴포넌트의 업데이트 작업이 끝난 후 호출하는 메서드 ->

 

3) 언마운트: 페이지에서 컴포넌트가 사라짐

언마운트하기

componentWillUnmount:컴포넌트가 웹 브라우저상에서 사라지기 전에 호출되는 메서드

함수형 컴포넌트

useEffect: 컴포넌트가 마운트 됐을 때, 언마운트 됐을 때, 업데이트 될 때 특정작업을 처리하는 hook

 


 

userarr-react

 

App.js

import './App.css';
import UserList from './components/UserList';
import { useState, useRef } from 'react'; 
import CreateUser from './components/CreateUser';

function App() {
  // CreateUser의 입력 Input 상태관리
  const [ inputs, setInputs ] =useState({
    username:"",
    email:"",
  });
  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]:value
    })
    console.log(inputs);
  }
  const { username, email} = inputs;
  // useState() 실행 -> arr return
  // arr[0] = 상태
  // arr[1] = 상태를 변경해주는 함수
  const [ users, setUsers ] = useState([
    {
        id: 1,
        username:'green',
        email: 'green@gmail.com',
        active: false,
    },
    {
        id: 2,
        username:'blue',
        email: 'blue@gmail.com',
        active: false,
    },
    {
        id: 3,
        username:'yellow',
        email: 'yellow@gmail.com',
        active: false,
    }
])
const nextId = useRef(4);
// 배열에 새로운 항목을 추가하는 함수
// users배열에 새로운 user객체를 추가

const onCreate= () => {
  // 새로운 user객체 생성
  // const user = {
  //   id: nextId.current,
  //   username,
  //   email,
  // }
  const user = {
    id:nextId.current,
    username,
    email,
  }
  // const arr = [1, 2, 3, 4, 5];
  // [1, 2, 3 ,4 ,5 ,6]
  // arr = [...arr, 6]
  setUsers([...users,user]);
  setInputs({
    username:"",
    email:"",
  })
  nextId.current +=1;   // ref객체는 current에 담겨있음
}
// users배열에 해당 id는 삭제
// filter -> 해당하는 id와 user 객체의 id가 다른 객체만 새배열로 반환
const onDelete = (id) => {
  setUsers(users.filter(user=> id !== user.id));
}
const onToggle = (id) => {
  // 배열메서드 map 
  setUsers(users.map(user=> id===user.id ? {...user, active: !user.active} : user))
}
  return (
    <div className="App">
        <CreateUser email={email} username={username} onChange={onChange}
        onCreate={onCreate} />
        <UserList users={users} onDelete={onDelete} onToggle={onToggle}/>
    </div>
  );
}

export default App;

 

App_Reducer.js (Reducer 버전)

import './App.css';
import UserList from './components/UserList';
import { useState, useRef, useReducer } from 'react'; 
import CreateUser from './components/CreateUser';

const initialState = {
  inputs: {
    username:"",
    email:"",
  },
  users: [
    {
        id: 1,
        username:'green',
        email: 'green@gmail.com',
        active: false,
    },
    {
        id: 2,
        username:'blue',
        email: 'blue@gmail.com',
        active: false,
    },
    {
        id: 3,
        username:'yellow',
        email: 'yellow@gmail.com',
        active: false,
    }
]
}
function reducer(state, action) {
  switch(action.type) {
    case "CHANGE_INPUT":
    return {
        ...state,
    inputs: {
        ...state.inputs,
        [action.name]: action.value
    }
};
    case "CREATE_USER":
    return {
        inputs: initialState.inputs,
        users: state.users.concat(action.user)
        // users: [...state.users, user]
    };
    case "DELETE_USER":
    return {
        ...state,
        users: state.users.filter(user => user.id !== action.id)
    };
    case "ACTIVE_USER":
    return {
        ...state,
        users: state.users.map(user => 
            user.id === action.id ? {...user, active: !user.active } : user)
    };
    default:
    return state;
  }

}
function App() {
  // useReducer로 상태관리
  const [ state, dispatch ] = useReducer(reducer, initialState);
  //객체 구조분해할당
  const { users } = state;
  const { username, email } = state.inputs;  
  const onChange = (e) => {
  const { name, value } = e.target;
    dispatch({
        type: "CHANGE_INPUT",
        name: name,
        value: value
    })
  }
  const onCreate = () => {
    dispatch({
        type: "CREATE_USER",
        user: {
            id: nextId.current,
            username: username,
            email: email,
        }
    })
    nextId.current += 1;
  }
  const nextId = useRef(4);
  const onDelete = (id) => {
    dispatch({
        type: "DELETE_USER",
        id: id
    })
  }
  const onToggle = (id) => {
    dispatch({
        type: "ACTIVE_USER",
        id: id
    })
  }

  return (
    <div className="App">
        <CreateUser email={email} username={username} onChange={onChange}
        onCreate={onCreate} />
        <UserList users={users} onDelete={onDelete} onToggle={onToggle}/>
    </div>
  );
}

export default App;

 

CreateUser.js

import React from 'react';

const CreateUser = ({username, email, onChange, onCreate}) => {
    return (
        <div>
            <input name="username" placeholder="이름" value = {username}
            onChange={onChange}/>
            <input name="email" placeholder="이메일" value = {email}
            onChange={onChange}/>
            <button onClick={onCreate}>등록</button>
        </div>
    );
};

export default CreateUser;

 

UserList.js

import React, { useEffect } from 'react';
import './UserStyle.css'
const User = ({user, onDelete, onToggle}) => {
    useEffect(()=>{
        console.log('컴포넌트가 화면에 나타남');
        return () => {
            console.log('컴포넌트가 화면에서 사라짐');
        }
    }, [])
    return (
        <div>
            <span className={user.active ? 'active': ""} onClick={()=>{onToggle(user.id) }}>
            유저네임: {user.username}
            이메일: {user.email}
            </span>
            <button onClick={()=>{
                onDelete(user.id);
                }}>삭제</button>
        </div>
    )
}

const UserList = ({users, onDelete, onToggle}) => {
    // const users = [
    //     {
    //         id: 1,
    //         username:'green',
    //         email: 'green@gmail.com'
    //     },
    //     {
    //         id: 2,
    //         username:'blue',
    //         email: 'blue@gmail.com'
    //     },
    //     {
    //         id: 3,
    //         username:'yellow',
    //         email: 'yellow@gmail.com'
    //     }
    // ]
    return (
        <div>
            {users.map(user =><User user={user} key={user.id} onDelete={onDelete} onToggle={onToggle}/> )}
            {/* <UserList users={users}/> */}
        </div>
    );
};



export default UserList;

 

UserStyle.css

.active {
    background-color: lightcyan;
}

 

 

 

 

 

 

 

App2.js

import React, { useEffect, useState } from 'react';

const App2 = (props) => {
    const [ count, setCount ] = useState(1);
    const [ input, setInput ] = useState("");
    useEffect(()=>{
        // componentDidMount && cononentDidUpdate
        console.log('렌더링 될 때마다 useEffect 호출')
    })
    
    // useEffect에 두번 째 인자로 []을 넘겨주면 마운트 될때만 호출됨
    // conponentDidMount 
    useEffect(()=>{
        console.log('처음 마운트 될 때만 useEffect 호출')
    }, [])

    useEffect(()=>{
        console.log('배열요소안의 값이 업데이트 되면 useEffect 호출')
    }, [count])

    const handleCount = () => {
        setCount(count+1);
    }

    const onChange = (e) => {
        setInput(e.target.value);
    }
    return (
        <div>
            <button onClick={handleCount}>수정하기</button>
            <span>count: {count}</span>
            <input onChange={onChange} value={input}/>
        </div>
    );
};

export default App2;

 

 

App3.js

import React, { useState } from 'react';
import Timer from './components/Timer';

const App3 = (props) => {
    const [showTimer, setShowTimer] = useState(false);
    return (
        <div>
            { showTimer && <Timer/>}
            <button onClick={()=>{setShowTimer(!showTimer)}}>클릭하세요</button>
        </div>
    );
};

export default App3;

 

Components/Timer.js

import React, { useEffect } from 'react';

const Timer = (props) => {
    // Mount 할 때 호출 componentDidMount
    // UnMount할 때 호추 componentWillUnmount
    // Update 할 때 호출 componentDidUpdate
    useEffect(()=>{
        const timer = setInterval(() => {
            console.log('타이머 돌아가는중 ...');
        }, 1000)
        return () => {
            clearInterval(timer);
        }
    }, [])
    return (
        <div>
            타이머를 실행합니다.
        </div>
    );
};

export default Timer;

 

 

 

App4.js

import React, { Component, useState, useEffect } from 'react';

const App4 = (props) => {
    // 클래스 컴포넌트 보이기
    const [funcShow, setFuncShow] = useState(true);
    return (
        <div>
            <h1>hello world</h1>
            <input type="button" value="클래스 컴포넌트 보이기/안보이기" onClick={()=>setFuncShow(!funcShow)}/>
            { funcShow && <ClassComp initNumber={2}/> }
        </div>
    );
};
// class컴포넌트 만들기
class ClassComp extends Component {
    // state 생성
    // props 값을 sate 값으로 지정
    state = {
        number: this.props.initNumber,
        date: new Date().toLocaleTimeString(),
    }
    // 랜더가 끝난다음 실행사이클 메서드
    componentDidMount() {
        console.log("class형 컴포넌트 => componentDidMount");
    }
    // 컴포넌트 UnMount되기 직전 실행사이클 메서드
    componentWillUnmount() {
        console.log("class형 컴포넌트 => componentWillUnmount");
    }
    render() {
        console.log("class형 컴포넌트 => render")
        return(
            <div className='container'>
                <h2>클래스 컴포넌트</h2>
                <p>Number: <span>{this.state.number}</span></p>
                <p>Date: <span>{this.state.date}</span></p>
            </div>
        )
    }
}

export default App4;

'Stack > React' 카테고리의 다른 글

[React] React Component Styling  (0) 2022.06.23
[React] to-do list  (0) 2022.06.22
[React] event-react(Event / ref)  (0) 2022.06.21
[React] 컴포넌트  (0) 2022.06.20
[React] 안녕 ~ React  (0) 2022.06.20
'Stack/React' 카테고리의 다른 글
  • [React] React Component Styling
  • [React] to-do list
  • [React] event-react(Event / ref)
  • [React] 컴포넌트
7ingout
7ingout
  • 7ingout
    Hello, 7ingout world!
    7ingout
  • 전체
    오늘
    어제
    • 분류 전체보기 (205)
      • Project (5)
      • Stack (173)
        • React (40)
        • JavaScript (50)
        • TypeScript (14)
        • HTML (11)
        • CSS (31)
        • Spring (9)
        • PHP (15)
        • SQL (3)
        • Python (0)
      • ETC (9)
      • Design (13)
        • Illustrator (6)
        • Photoshop (7)
      • Articloid (4)
        • 7ingout (4)
  • 공지사항

    • ☻
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
7ingout
[React] 라이프 사이클 메서드(Life Cycle Method)
상단으로

티스토리툴바