본문 바로가기
코리아 IT아카데미/react.js

3일차 | react2

by Sharon kim 2022. 3. 10.

 

component > createUser.jsx

import React from 'react';

function CreateUser({ username, email, onChange, onCreate }) {
    
    return (
      <div>
        <input
          name="username"
          placeholder="이름을 입력하세요"
          onChange={onChange}
          value={username}
        />
        <input
          name="email"
          placeholder="이메일을 입력하세요"
          onChange={onChange}
          value={email}
        />
        <button onClick={onCreate}>등록</button>
      </div>
    );
}

export default CreateUser;

component > userList01.jsx

import React, { useEffect } from 'react';

function User({ user, onRemove, onToggle }) {

  // useEffect( () => {
  //     // console.log('컴포넌트가 화면에 나타남');
  //     console.log(user);
  //     console.log('user 값이 설정되었음');
  //     return () => {
  //         // console.log('컴포넌트가 화면에서 사라짐');
  //         console.log(user);
  //         console.log('user가 바뀌기 전...');
  //     };
  // }, [user]);

  // deps 파라미터 생략 : 컴포넌트가 리렌더링 될 때마다 무조건 호출

  useEffect(() => {
    console.log(user);
  });

  return (
    <div>
      <b
        style={{
          cursor: "pointer",
          color: user.active ? "deeppink" : "black",
        }}
        onClick={() => onToggle(user.id)}
      >
        {user.username}
      </b>{" "}
      <span>({user.email})</span>
      &nbsp;&nbsp;
      <button onClick={() => onRemove(user.id)}>삭제</button>
    </div>
  );
}

function UserList01({ users, onRemove, onToggle }) {

  return (
    <div>
      {users.map(user => (
        <User user={user} key={user.id} onRemove={onRemove} onToggle={onToggle} />
      ))}
    </div>
  )
}

export default UserList01;

App.js

import React, { useRef, useState, useMemo } from "react";
// import Counter from './component/counter';
// import Input from './component/Input';
// import MutiInput from "./component/MutiInput";
// import UserList from "./component/UserList";
import UserList01 from "./component/userList01";
import CreateUser from "./component/createUser";

function countActiveUser(users) {
  console.log('선택된 사용자 수');
  return users.filter(user => user.active).length;
}

function App() {

  //초기값 설정(userState 함수를 사용)
  //const [값, 처리할 함수]
  const [inputs, setInputs] = useState({
    username: '',
    email: ''
  })
  //userRef  dom 접근
  const { username, email } = inputs;

  const onChange = e => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,//객체 복사
      [name]: value
    });
  }

  const [users, setUsers] = useState([
    {
      id: 1,
      username: "김사과",
      email: "apple@apple.com",
    },
    {
      id: 2,
      username: "오렌지",
      email: "orange@orange.com",
    },
    {
      id: 3,
      username: "반하나",
      email: "banana@banana.com",
    },
    {
      id: 4,
      username: "이메론",
      email: "melon@melon.com",
    },
    {
      id: 5,
      username: "배애리",
      email: "berry@berry.com",
    },
  ]);

  //useRef
  const nextId = useRef(6);

  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    }

    //배열의 객체 추가
    setUsers([...users, user]);
    setInputs({
      username: "",
      email: "",
    });
    nextId.current += 1;
  }

  const onRemove = id => {
    //user.id 가 파라미터로 
    setUsers(users.filter(user => user.id !== id));
  }

  const onToggle = id => {
    setUsers(
      users.map(user => user.id === id ? { ...user, active: !user.active } : user));
  }

  const count = useMemo(() => countActiveUser(users), [users]);


  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate} />
      <UserList01 users={users} onRemove={onRemove} onToggle={onToggle} />
      <div>선택된 사용자 수 : {count}</div>
    </>
  );
}

export default App;

 

리액트 
-사용자 UI를 만들기 위한 자바스크립트 라이브러리
-앵귤러(프레임워크), 뷰(프레임워크와 라이이브러리 중간단계)

프레임워크  = 집(건축물)
라이브러리 = 도구, 인테리어 제품

컴퍼넌트
- 리액트에서 레고 조각처럼 조합하여 프로그래밍 할 수 있도록 만드 모듈단위
- 함수형과 클래스형

컴포넌트를 만드는 방법

                    class                   function
                상태를 관리(o)       상태 관리(x) -> 리액트 16.8버전 부터 가능하게 됨


[함수형 컴포넌트] => 선호

import React from 'react'; 

function Test(){


    return (
        <div>
            리액트 컴포넌트 테스트입니다
        </div>
    );
}

export default Test;


[클래스형 컴포넌트]❓

  class Tests extends React.Component {
    render() {
        return (
            <>
              리액트 컴포넌트 테스트입니다
            </>
        );
    }
}

export default Test;


JSX
리액트와 마찬가지로 페이스북에서 개발한 확장 구문입니다. 
- UI를 화면에 나타태는 파일을 만들어가는 것(실제는 자바스크립트)
- 태그는 꼭 닫혀야합니다.
- 두개 이상의 태그는 하나의 태그로 감싸져야 함
- css 속성은 카멜케이스 표기법

태그에 style과 CSS class를 설정하는 방법
스네이트 표기법  ->  카멜케이스 표기법(낙타표기법)
background-color -> backgroundColor

css파일을 별도로 만드는 경우
- import 
- className 속성으로 등록
 
- 주석을 작성하는 방법
{ /* */ }


비구조할당
- 객체 안에 있는 값을 추출해서 변수 혹은 상수에 저장 

const student = {'apple':'김사과'.'banana':'오렌지','orange':'반하나'}
                       -------  -------
                        key     value
const = {apple, banana, orange} =student;


props(properties)

* props를 통해 컴포넌트에게 값 전달하는 방법

<태그 속성="값"></태그>
<컴포넌트명 속성명1=값1 속성명2=값2/>

function 컴포넌트명(props){
   return <div>{props.속성}</div>    
}


function 컴포넌트명(props){
      "props.속성명" 으로 사용 
}

function 컴포넌트명({속성명1, 속성명2}){
    "속성명1" 으로 사용
}


* 기본값을 설정하는 방법
defaultProps -> 컴포넌트에 props를 지정하지 않았을 때  기본값을 설정
컴포넌트명.defaultProps = {
    설정할 내용
}

props.children
* 컴포넌트 태그 사이에 넣은 값을 조회하는 방법
function 컴포넌트명({ children }){

    return (
        <div>
            { children }
        </div>
    )
}


조건부 렌더링
특정 조건에 따라 다른 결과물을 렌더링하는 것을 의미합니다.
1. 조건식이 true인 경우와 false인 경우 모두 표현
{조건식 ? true인 경우 : false인 경우}

2.조건식이 true인 경우만 표현
{조건식 && true인 경우}

Hook함수{useState, }
상태관리를 다루는 클래스를 좀 더 쉽게 다룰 수 있도록 만들어진 함수

useState
리액트에서 값의 상태를 관리하는 Hooks입니다. 
즉 컴포넌트에서 동적인 값의 상태(state)를 다루는 Hook함수
리액트 16.8버전 부터 Hooks라는 기능이 도입되면서 
함수형 컴포넌트에서도 상태를 관리할 수 있게 되었습니다. 

const [현재상태변수, 설정함수] = useState(초기값); 
const [number, setNumber] = useState(0);  // 배열에 따른 비구조 할당

원래
const numberState = useState(0);
const number = numberState(0);
const setNumber = numberState(0);

spread
- 객체 또는 배열을 펼쳐 저장할 수 있음

const dog ={
  name:'루시'
};
const cutdog ={
  ...dog,
  age:10
};
const whitecutdog ={
  ...cutdog ,
  color:'white'
};

inputs[name] = value 이런식으로 기존 상태를 직접 수정하게 되면, 값이 바뀌어도 리랜더링이 일어나지 않습니다.

- 리액트에서 상태값의 불변성을 지켜줘야 함
- 리액트 컴포넌트에서 상태가 업데이트 되었음을 감지할 수 있음.
- 리액트에서 객체를 업데이트 할 때는 기본 객체를 직접 수정하면 안되고 새로운 객체를 만들었어  
  새 객체에 변화를 줘야 함

불변성을 지켜주어야만 리엑트 컴포넌트에서 상태가 업데이트가 됐음을 감지할 수 있고 이에 따라 필요한 리렌더링이 진행됩니다.

useRef로 특정 DOM 선택하기
리액트에서 DOM에 직접 접근하는 방법을 사용하기 위해 useRef라는 Hooks를 사용합니다.

userRef 함수( 함수를 클래스처럼 사용)
      - 특정 엘리먼트에 접근하거나 스크롤바 위치를 설정할때
      - 외부 라이브러리를 사용할 때 


useEffect
컴포넌트가 마운트(처음 나타났을 때) 됐을 때, 언마운트(사라질 때) 됐을 때, 그리고 업데이트(특정 props가 바뀔 때) 될 때 특정 작업을 처리할 수 있습니다.

컴포넌트가 마운트시 하는 작업
- props로 받은 값을 컴포넌트의 로컬 상태로 설정
- 외부 API 요청(REST API등..)
- 라이브러리 사용
- setInterval을 통한 반복작업 또는 setTimeout을 통한 작업 예약

컴포넌트가 언마운트시 하는 작업
- 라이브러리 인스턴스 제거
- setInterval, setTimeout을 사용하여 등록한 작업을 clear 할때

useEffect(함수, 배열)
함수 : 처음 컴퍼넌트가 나타날 때 실행할 함수
배열 : 의존값이 들어있는 배열, 만약 배열을 비우게 된다면 컴포넌트가 처음 나타날 때만 useEffect에 등록한 함수가 호출됨

cleanup 함수
useEffect에서는 함수를 반환할 수 있음. useEffect에 대한 뒷정리를 합니다. deps가 비어있는 경우에 컴포넌트가 사라질 때 cleanup 함수가 호출됨


useMemo
성능 최적화를 위해 연산된 값을 재사용합니다.

 

 

'코리아 IT아카데미 > react.js' 카테고리의 다른 글

6일차 | react_Route  (0) 2022.03.16
5일차 | react4(Icon, styled)  (0) 2022.03.14
4,5,6일차 | react3(todoList)  (0) 2022.03.10
2일차 | react2  (0) 2022.03.07
1일차 | react 기본  (0) 2022.03.03