useEffect

화면에 컴포넌트가 렌더링(마운트)/리렌더링 되거나 수정,제거 등의 변경 전(언마운트)에 효과를 주기위해 사용.

 

 

마운트 시점에 콘솔로 확인

마운트시점이란 컴포넌트요소가 화면에 렌더링될 때를 말합니다. 구체적으로 말하면 페이지를 맨처음 로딩할 때, 또 어떤 값을 수정/제거하여 변경된 내용이 다시 로딩될 때입니다. 이러한 상황은 props로 받은 값을 useState로 설정(관리)하거나 외부 Api요청시, setInterval, setTimeout설정, url체크하여 렌더링할 요소를 설정할 때 등이 있습니다.

 

ArrayList.js에서 useEffect를 사용하기위해 먼저 import를 해줍니다. 그리고 아래와 같이 화면출력코드가 있는 TempInfo()항목에 useEffect로 실행될 코드를 선언해줍니다. 렌더링되는 시점에 "렌더링" 텍스트와 tempInfo내용이 출력되도록 해보겠습니다.

import React, { useEffect } from 'react';

function TempInfo({ tempInfo, onRemove, onToggle }) {

  useEffect(() => {
    console.log("렌더링", tempInfo);
  }, [tempInfo]);


  return (
    <div>
        <b style={{
          color: tempInfo.active ? 'orange' : 'black',
          cursor: 'pointer'
        }} onClick={() => onToggle(tempInfo.id)}>
        {tempInfo.username}</b> {tempInfo.email} 
        <button onClick={() => onRemove(tempInfo.id)}>삭제</button>
    </div>
  )
}

function RenderTempInfoArray({ tempInfoArray, onRemove, onToggle }) {

  return (
    <>
      {
        tempInfoArray.map(
          tempInfo => (<TempInfo tempInfo={tempInfo} key={tempInfo.id} onRemove={onRemove} onToggle={onToggle} />)
        )
      }
    </>
  )
}

export default RenderTempInfoArray;

 

처음 로딩화면 - 

 

Anne2리스트를 클릭하여 수정한 내용이 렌더링될 때

 

Anne4를 추가등록한 후 변경내용이 렌더링될 때

 

주의할 점은 배열로 [tempInfo]를 넣은 부분인데요, 디펜던시(deps)라고 부르는 useEffect관리대상(값 또는 function도 포함)을 넣어주지 않으면 이부분의 코드를 변경된 특정 값에 대해만 실행하는게 아니라 추가/수정시 tempInfo를 포함하는 tempInfoArray의 모든 리스트 수만큼, 또 useState로 관리되는 input의 onChange의 모든 상황마다 매번 계속해서 실행하게 됩니다. 불필요하게 코드가 계속 실행되는 거죠. 

useEffect(() => {
    코드부분
  }, [tempInfo]);

 

그리고 만약 디펜던시(deps)영역을 빈 배열형태로 넣으면 로딩 후 변경된 값이 체크안되서 이전의 값을 참고하게 될 수 있으므로 관리대상값은 꼭 deps배열안에 추가를 해주어야 합니다. 

 

 

 

 

언마운트 시점에 콘솔로 확인

언마운트상황은 수정/제거등의 변경진행 전 시점에 효과를 주기위해 사용됩니다. 라이브러리 인스턴스를 제거하던가 setInterval/setTimeout해뒀던 요소를 변경하기위해 clearInterval/clearTimeout하는 상황들을 예로 들 수 있습니다.

 

ArrayList.js에서 추가해줬던 useEffect선언부분에 return부분을 추가해줍니다.

 

  useEffect(() => {
    console.log("렌더링", tempInfo);
    return () => {
      console.log("리렌더링 전", tempInfo);
    }
  }, [tempInfo]);

 

Anne1을 클릭하여 수정시 렌더링전(언마운트)의 active: true값이 출력되고 바로 수정된 false값이 출력(마운트)됩니다.

Anne3을 삭제하기 전 상태값을 출력합니다. 삭제된 리스트항목은 출력할 수 없으므로 렌더링text는 출력되지 않습니다.

'React.js > React 입문 - Just 따라하기' 카테고리의 다른 글

배열(Array) 항목 수정  (0) 2020.06.21
배열(Array) 항목 제거  (0) 2020.06.21
배열(Array)에 항목 추가  (0) 2020.06.21
배열(Array)정보를 화면에 Rendering  (0) 2020.06.20
useRef로 DOM선택  (0) 2020.06.20

먼저 만들어둔 ArrayList.js에 배열항목 수정기능을 추가해봅니다. 형태는 브라우저화면에서 리스트별 username부분 클릭시 text컬러가 변경되는데 이 컬러가 배열안의 'active'라는 key값이 true/false로 바뀌면서 화면에 변경된 컬러로 적용(toggle)되는 방식입니다.

 

화면렌더링되는 TempInfo 리턴부분에 style을 넣어주는데 tempInfo.active값이 참일때 orange컬러로, 거짓일때 black컬러로 변경되도록 합니다. (마우스클릭 영역표시를 위해 커서 pointer도 추가)

그리고 App.js에서 선언할 toggle기능을 받아오기위해 파라미터에 onToggle을 TempInfo()와 RenderTempInfoArray부분에 추가합니다. TempInfo 전달할 속성명도 추가해줍니다.

 

import React from 'react';

function TempInfo({ tempInfo, onRemove, onToggle }) {
  return (
    <div>
        <b style={{
          color: tempInfo.active ? 'orange' : 'black',
          cursor: 'pointer'
        }} onClick={() => onToggle(tempInfo.id)}>
        {tempInfo.username}</b> {tempInfo.email} 
        <button onClick={() => onRemove(tempInfo.id)}>삭제</button>
    </div>
  )
}

function RenderTempInfoArray({ tempInfoArray, onRemove, onToggle }) {

  return (
    <>
      {
        tempInfoArray.map(
          tempInfo => (
            <TempInfo 
                tempInfo={tempInfo}  
                key={tempInfo.id} 
                onRemove={onRemove} 
                onToggle={onToggle}
             />
          )
        )
      }
    </>
  )
}

export default RenderTempInfoArray;

 

그 다음 App.js에서 onToggle기능을 넣어줍니다.

tempInfoArray의 배열원소마다 useState로 값을 새로 set하는데요, onToggle이벤트시 전달된 id값과 동일한 배열원소는 active값을 반전시키고 아닌 원소는 그대로 둡니다.

 

import React, { useRef, useState } from 'react';
import ArrayList from './ArrayList';
import ArrayInsert from './ArrayInsert';

function App() {
  const [tempInfoArray, setTempInfoArray] = useState([
    {
      id: 1,
      username: 'Anne1',
      email: 'anne1@gmail.com',
      active: true,
    },
    {
      id: 2,
      username: 'Anne2',
      email: 'anne2@gmail.com',
      active: true,
    },
    {
      id: 3,
      username: 'Anne3',
      email: 'anne3@gmail.com',
      active: false,
    }
  ]);

  const [inputVal, setInputVal] = useState({
    username: '',
    email: ''
  });

  const { username, email } = inputVal;

  const onChange = e => {
    const { name, value } = e.target;
    setInputVal({
      ...inputVal,
      [name] : value
    })
  }

  const nextId = useRef(4);

  const onInsertArray = () => {
    const newTempInfo = {
      id: nextId.current,
      username: username,
      email: email
    }
    //setTempInfoArray([...tempInfoArray, newTempInfo]);
    setTempInfoArray(tempInfoArray.concat(newTempInfo));

    setInputVal({
      username: '',
      email: ''
    })
    
    nextId.current += 1;
  }

  const onRemove = id => {
    setTempInfoArray(tempInfoArray.filter(tempInfo => tempInfo.id !== id));
  }	
    
  const onToggle = id => {
    setTempInfoArray(tempInfoArray.map(
      tempInfo => tempInfo.id === id ? { ...tempInfo, active : !tempInfo.active } : tempInfo
    ))
  }
	
  return (
    <>
      <ArrayInsert 
        username={username}
        email={email}
        onChange={onChange}
        onInsertArray={onInsertArray}
    />
     <ArrayList tempInfoArray={tempInfoArray} onRemove={onRemove} onToggle={onToggle} />
    </>
  );
}

export default App;

 

이전에 작업해둔 ArrayList.js파일에서 배열리스트마다 삭제가 가능하도록 TempInfo()의 화면 렌더링코드부분에 삭제버튼코드를 넣어줍니다. 그리고 해당 삭제이벤트는 RanderTempInfoArray()에서 map()에 의해 파라미터로 받을 것이므로 각 속성과 파라미터를 지정해줍니다. 이때 onRemove함수는 렌더링동시에 실행될 것이 아니라 클릭시 시작되야하므로 호출형식이 아닌 아래 코드와 같은 방식으로 넣어줍니다.

 

import React from 'react';

function TempInfo({ tempInfo, onRemove }) {
  return (
    <div>
        <b>{tempInfo.username}</b> {tempInfo.email} 
        <button onClick={() => onRemove(tempInfo.id)}>삭제</button>
    </div>
  )
}

function RenderTempInfoArray({ tempInfoArray, onRemove }) {

  return (
    <>
      {
        tempInfoArray.map(
          tempInfo => (<TempInfo tempInfo={tempInfo}  key={tempInfo.id} onRemove={onRemove} />)
        )
      }
    </>
  )
}

export default RenderTempInfoArray;

 

RenderTempInfoArray()부분에서도 onRemove기능을 외부에서 받아와야하므로 파라미터를 추가해주고 또 그 기능을  <TempInfo>컴포넌트에 전달하기위해 속성을 추가해줍니다.

 

이번에는 App.js에서 onRemove기능을 만들어줄 차례입니다. 삭제기능의 순서(또는 구조)를 요약해보겠습니다.

  • ArrayList.js파일의 TempInfo()에 의해 출력된 삭제버튼마다 등록된 onRemove()는 각각의 id값을 매개변수로 가짐
  • 버튼클릭시 해당 id값을 가지고 App.js에서 선언된 onRemove를 호출
  • onRemove는 id값을 파라미터로 받아 useState로 관리되는 tempInfoArray를 setTempInfoArray로 다시 저장할 준비
  • setTempInfoArray를 실행할 때 파라미터로받은 id값이 아닌 배열요소만 filter함수로 걸러냄
  • 걸러진 id값외의 배열요소들만 useState의 tempInfoArray에 남게됨

 

결국 남게된 tempInfoArray의 배열요소만 다시 화면에 렌더링되는 것입니다.

 

import React, { useRef, useState } from 'react';
import ArrayList from './ArrayList';
import ArrayInsert from './ArrayInsert';

function App() {
  const [tempInfoArray, setTempInfoArray] = useState([
    {
      id: 1,
      username: 'Anne1',
      email: 'anne1@gmail.com'
    },
    {
      id: 2,
      username: 'Anne2',
      email: 'anne2@gmail.com'
    },
    {
      id: 3,
      username: 'Anne3',
      email: 'anne3@gmail.com'
    }
  ]);

  const [inputVal, setInputVal] = useState({
    username: '',
    email: ''
  });

  const { username, email } = inputVal;

  const onChange = e => {
    const { name, value } = e.target;
    setInputVal({
      ...inputVal,
      [name] : value
    })
  }

  const nextId = useRef(4);

  const onInsertArray = () => {
    const newTempInfo = {
      id: nextId.current,
      username: username,
      email: email
    }
    //setTempInfoArray([...tempInfoArray, newTempInfo]);
    setTempInfoArray(tempInfoArray.concat(newTempInfo));

    setInputVal({
      username: '',
      email: ''
    })
    
    nextId.current += 1;
  }

  const onRemove = id => {
    setTempInfoArray(tempInfoArray.filter(tempInfo => tempInfo.id !== id));
  }

  return (
    <>
      <ArrayInsert 
        username={username}
        email={email}
        onChange={onChange}
        onInsertArray={onInsertArray}
    />
     <ArrayList tempInfoArray={tempInfoArray} onRemove={onRemove} />
    </>
  );
}

export default App;

 

결과화면입니다. 삭제버튼을 클릭하면 해당리스트가 삭제됩니다.

 

배열에 항목을 추가하는 예제를 위해 이전 글에서 사용했던 App.js와 ArrayList.js를 그대로 활용해보겠습니다.

코드 상태는 아래 이미지를 참고해주세요.

 

 

준비가 됬으면 이제 새로 ArrayInsert.js파일을 만듭니다. username과 email을 새로 추가하기 위한 컴포넌트입니다. 사용할 속성값과 이벤트기능은 파라미터로 받아서 처리할 것이므로 아래와 같이 작성해줍니다.

 

 

그 다음 App.js파일에서 배열추가를 위한 기본형태를 만들어줍니다.

방금만든 입력폼 컴포넌트를 화면에 렌더링하기위해 ArrayInsert를 import해줍니다. 그리고 id값이 자동증가되도록 값관리를 위해 React와 함께 { useRef }도 불러줍니다.

변수 nextId를 만들어 4값을 기본으로 초기화해주고, onInsertArray시 nextId의 값을 콘솔로 확인하기 위해 nextId.current를 입력합니다. 또 클릭시마다 이 값이 증가되도록 코딩해줍니다.

 

 

 

브라우저에서 등록버튼을 누르면 onInsertArray이벤트가 발생하면서 콘솔에 nextId값이 4부터 증가된 값이 찍히는 것을 확인할 수 있습니다.

 

그러면 이제 본격적인 작업을 위해 아래목록의 요소들을 추가할 것입니다.

  • useState로 현재값과 새로 세팅될 값 관리위한 대상 적용(tempInfoArray, input들)
  • input의 onChange이벤트시 대상 input마다 name과 value값을 얻어 useState관리대상값으로 다시 세팅
  • onInsertArray이벤트시 새로 저장할 array요소(newTempInfo) 변수로 담기
  • onInsertArray이벤트시 newTempInfo를 useState로 관리하기위해 setTempInfoArray로 세팅
  • onInsertArray이벤트시 등록버튼 클릭후 input을 빈값으로 초기화
  • <ArrayInsert>컴포넌트에 넘겨줄 속성들 세팅

 

import React, { useRef, useState } from 'react';
import ArrayList from './ArrayList';
import ArrayInsert from './ArrayInsert';

function App() {
  const [tempInfoArray, setTempInfoArray] = useState([
    {
      id: 1,
      username: 'Anne1',
      email: 'anne1@gmail.com'
    },
    {
      id: 2,
      username: 'Anne2',
      email: 'anne2@gmail.com'
    },
    {
      id: 3,
      username: 'Anne3',
      email: 'anne3@gmail.com'
    }
  ]);

  const [inputVal, setInputVal] = useState({
    username: '',
    email: ''
  });

  const { username, email } = inputVal;

  const onChange = e => {
    const { name, value } = e.target;
    setInputVal({
      ...inputVal,
      [name] : value
    })
  }

  const nextId = useRef(4);

  const onInsertArray = () => {
    const newTempInfo = {
      id: nextId.current,
      username: username,
      email: email
    }
    
    setTempInfoArray([...tempInfoArray, newTempInfo]);
    //setTempInfoArray(tempInfoArray.concat(newTempInfo)); // 윗 줄의 ...연산자 사용시와 동일 결과

    setInputVal({
      username: '',
      email: ''
    })
    nextId.current += 1;
  }

  return (
    <>
      <ArrayInsert 
        username={username}
        email={email}
        onChange={onChange}
        onInsertArray={onInsertArray}
    />
     <ArrayList tempInfoArray={tempInfoArray} />
    </>
  );
}

export default App;

 

브라우저에서 등록버튼을 누르면 입력한 값이 새로 출력되는 것을 확인할 수 있습니다.

위의 그림과 같이 배열정보 tempInfoArray를 화면에 출력해보겠습니다.

 

 

단순 index지정 배열렌더링

먼저 ArrayList.js를 생성하여 RenderTempInfoArray()를 만들고 그 안에 위의 배열을 넣어줍니다. 그리고 RenderTempInfoArray를 App.js에서 사용할 수 있도록 export해줍니다.

 

그리고 App.js에서 Array.js를 불러옵니다.

 

 

기본 준비를 마치고 이제 return할 형태를 만들껀데요. TempInfo라는 컴포넌트 태그요소를 만들어 각 배열원소가 TempInfo태그형태에 들어가도록 할 것입니다. RenderTempInfoArray()의 tempInfoArray를 tempInfo이름의 파라미터로 받을 수 있도록 아래 이미지(3~9번 라인)와 같이 코딩해줍니다.

 

그리고 RenderTempInfoArray() 리턴부분에서 방금만든 <TempInfo>를 넣고 각 배열원소의 정보를 tempInfo를 통해 넣어줍니다. 그럼 브라우저화면에서 배열정보가 <TempInfo>형태로 출력되는 것을 확인할 수 있습니다.

 

 

 

 

map함수를 이용한 배열렌더링

화면은 잘 출력됬으나 코드상에서 return부분을 보면 배열을 인덱스별로 하나하나 지정해서 넣어줘야하는 불편이 있으므로 이 부분을 효율적으로 바꿔보겠습니다. 

{
  tempInfoList.map(
  	tempInfo => (<TempInfo tempInfo={tempInfo} key={tempInfo.id} />)
  )
}

 

React의 배열내장함수 map을 사용하여 각 배열원소에 공통적인 함수를 적용하는 것입니다.

이렇게 해서 배열원소가 많아지더라도 한꺼번에 처리할 수 있는 코드형태로 변경해보았습니다.

 

 

 

props를 이용한 외부데이터 배열렌더링

이번엔 tempInfoArray배열정보를 App.js로 옮기고 ArrayList.js에 props로 받아 출력하는 방식을 이용해보겠습니다.

먼저 App.js를 수정해줍니다. <ArrayList>태그에는 배열정보를 속성값으로 넘겨줍니다.

 

 

ArrayList.js에서는 RenderTempInfoArray에 props 파라미터로 받을 수 있도록 tempInfoArray를 추가해줍니다.

 

버튼클릭시 원하는 DOM(document object model)으로 focus를 이동시키는 기능을 만들어보겠습니다.

우선 SelectDom.js를 만들어 App.js에서 불러오겠습니다.

 

 

그리고나서 jsx부분에 input태그 3개를 넣어주는데요. 이때 포커스 이동을 위해 input마다 id를 주고 Go버튼 클릭 호출 함수에 document.getElementById('아이디명').focus(); 와 같은 방식으로 포커싱할 수도 있지만, useRef를 사용하여 선택할 대상을 지정해보겠습니다.

useState를 import했던 것처럼 useRef를 불러오고나서 useRef를 담을 변수를 만들어줍니다.

그런 다음, useRef를 사용할 input에 ref속성을 아래와 같이 넣어줍니다.

 

ref={useRef변수명};

 

useRef특징 : useRef로 관리하는 값은 그 값이 바뀌어도 컴포넌트가 다시 rendering되지 않음

이번에는 input 여러개를 한꺼번에 관리하는 방법을 알아보겠습니다. InputTest.js를 수정해서 사용할 것이므로 App.js는 먼저번에 작성한 그대로 사용합니다.

 

 

input하나만 관리할 때는 useState에서 바로 초기값을 넣어줬지만 이번엔 여러개의 초기값을 넣어야 하므로 중괄호{ }를 사용하여 객체형태로 넣어줍니다. 그리고 input마다 값이 입력될 때 해당값을 체크하기위해 chkVal()에서 target의 name값과 value를 콘솔로 출력을 해봅니다.

 

 

이번에는 chkVal()부분에서 동일한 상태이지만 코드를 더 편리하게 관리하도록 e.target부분에 개별명칭을 주겠습니다. 주의할 점은 e.target의 각 key값 name과 value를 가져온다는 의미이므로 name과 value의 이름을 변경하면 정상적인 값을 불러올 수가 없습니다.

 

 

위와같이 작성해도 정상동작하는 것을 확인할 수 있습니다.

 

 

그런 다음, input값 변경시 useState에 변경된 값을 등록하기 위해 chkVal()에서 setVal값을 넣어주겠습니다.

여러 개의 값을 한꺼번에 기억하고 관리해야하므로 val값들의 현재상태를 저장하기 위해 ...val을 추가해줍니다. 그리고나서 각 변경값을 적용할 위치에 {val.userName}과 {val.nickName}을 넣어줍니다.

resetVal에서도 객체형태로 초기화값을 선언해 줍니다.

 

 

그리고 위의 {val.userName}과 {val.nickName}을 축약해서 표현하기위해 코드를 조금 수정해봅니다.

useState의 val값 키들을 간단하게 사용하기 위해 다음과 같이 코드를 추가해줍니다. 그 다음 val값을 사용하는 위치에 해당 명칭을 다시 각각 넣어줍니다.

 

 

브라우저를 보면 동일하게 동작하는 것을 확인할 수 있습니다.

input에 입력된 값을 화면에 출력하고, 초기화버튼을 누르면 input값이 비워지는 기능을 만들어보겠습니다.

우선 InputTest 컴포넌트를 만들어줍니다.

 

 

그리고 App.js에서 InputTest를 불러옵니다.

 

 

그다음, input값이 변할 때마다 해당 값을 확인할 수 있게 onChange에 등록할 함수를 선언해줍니다. chkVal함수에 이벤트객체를 매개변수로 넣어주고 이벤트대상(input)의 value값을 콘솔로 확인해봅니다.

 

 

그리고나서 useState를 통해 현재값 {val}을 출력해줄 위치를 지정해줍니다.

input에 {val}을 넣어주는 이유는 초기화버튼클릭시 새로 지정된 빈 값('')이 input에도 적용되도록 하기 위해서입니다.

 

 

 

위의 코드를 해석하면 input의 변경된 값이 chkVal()의 setVal을 통해 useState에 등록되어 각각의 {val}위치에 적용되고, 초기화버튼 클릭시 빈 값이 resetVal()의 setVal을 통해 useState에 등록되어 또다시 각각의 {val}위치에 적용되는 것입니다.

 

컴포넌트안에서 +1/-1버튼을 누를 때마다 현재값에서 1씩 숫자가 변하는 카운터를 만들어보겠습니다. 

우선은 Counter.js를 생성하고 화면에 출력될 기본요소를 넣어줍니다.  저는 브라우저에서 가운데 정렬을 하기위한 간단한 스타일도 넣어주었습니다.

 

 

그리고 App.js에서 방금 만든 Counter.js를 불러옵니다.

 

 

그러면 화면에서 다음과 같이 렌더링 됩니다.

 

여기에서 다시 Counter.js로 돌아가 버튼클릭시 호출될 각각의 함수를 선언해주고, 버튼에 이벤트시 호출될 함수도 넣어줍니다. 주의할 점은 html에서 사용할 때 처럼 "onclick"이 아닌 카멜표기의 "onClick"이어야 합니다.

 

여기까지 완성되면 브라우저화면에서 각 버튼클릭시 콘솔창에서 +1과 -1이 찍히는 걸 볼 수 있습니다.

 

그러면 이제 마지막으로 Counter.js에서 useState를 통해 현재값을 체크하고 새로운 값을 출력해볼 차례입니다.

상단에서 React를 import했던 부분에 useState도 함께 불러줍니다.

 

import React, { useState } from 'react';

 

그리고 const변수를 추가해서 useState값을 넣어주는데요, 아래와 같이 추가해 줍니다. useState는 배열을 반환하는데 배열의 첫번째요소는 기존값을, 두번째요소는 새로 바뀔 값을 의미하게 됩니다. useState(0)은 처음 값을 0으로 넣어주겠다는 의미입니다.

const [num, setNum] = useState(0);

 

numPlus와 numMinus함수를 아래와 같이 수정해주고 값이 바뀔자리에 기존값 num을 넣어 준 뒤, 브라우저화면을 통해 확인해봅니다.

 

 

 

각각의 버튼을 클릭할 때마다 현재값에서 1씩 변하는 것을 확인할 수 있습니다.

그리고 버튼호출함수 부분을 아래와 같이 변경해도 동일하게 동작합니다.

  

우선 TestBox컴포넌트에 true 또는 false값을 전달하기 위해 App.js에서 다음과 같이 isPoint속성을 입력해줍니다.

true와 false는 일반 스트링이 아닌 자바스크립트값이므로 중괄호{ }안에 넣어줍니다.

 

 

 

조건부 랜더링 by 3항연산자

TestBox.js에서 값을 전달받기위해 파라미터에 isPoint를 넣어줍니다. 그리고 jsx안에서 자바스크립트를 실행하기 위해 중괄호안에 isPoint값에 따른 3항연산식을 넣어줍니다. 참이면 * 텍스트를, false일 경우는 아무것도 출력하지 않겠습니다.

 

 

결과화면을 보면 다음과 같이 나옵니다.

 

 

조건부 렌더링 by if문

if문을 사용하여 조건부 출력을 하기 위한 방법을 살펴봅니다. chkIsPoint함수를 만들어 if문을 넣었습니다. 함수를 jsx영역의 중괄호안에 직접 넣어 바로 호출해도 되지만 가독성이 좋도록 밖으로 빼두었습니다.

 

 

동일한 결과가 나오는 것을 확인할 수 있습니다.

만들어둔 TestHello컴포넌트안에 TestBox컴포넌트를 넣어보겠습니다.

 

TestHello.js를 import하고 아래와 같이 TestHello태그안에 TestBox태그를 넣어줍니다.

 

그리고나서 바로 브라우저를 확인하면

TestHello안의 내용만 나오고 TestBox내용은 나오지 않습니다.

이때 사용하는 것이 props children입니다. 파라미터자리에 {children}을 넣어주고, return할 태그내부에 출력할 컴포넌트인 {children}을 원하는 위치에 추가해줍니다.

 

 

그러면 아래와같이 TestHello내용과 TestBox내용이 모두 출력이 됩니다.

App.js에서 새로 만든 컴포넌트에 값을 전달해보고자 합니다.

 

미리 만들어둔 TestBox에 값을 전달할껀데요. TestBox태그부분에 name, boxNum, color 이렇게 3가지의 properties를 넣고 각각의 값을 입력합니다.

 

전달된 값 호출방법 01)

그리고 TestBox컴포넌트에서 function TestBox함수의 ( )파라미터 자리에 props를 넣어 각각의 properties를 위의 형식으로 불러줍니다. color프로퍼티스는 style에서 폰트색상변경을 위한 값으로, 나머지는 일반텍스트로 활용했습니다.

 

화면에 3개의 값이 잘 적용되었습니다. 

 

 

전달된 값 호출방법 02)

props를 넣었던 파라미터자리를 '구조분해'형식을 통해 각각의 개별 properties(속성)명을 넣어줍니다.

그러면 각각의 properties명을 바로 호출해서 사용할 수 있습니다.

 

 

기본값 세팅하기

컴포넌트명.defaultProps = {

}

위의 코드처럼 defaultProps의 기본값을 세팅할 속성명과 값을 넣어줍니다.

그리고 App.js에서 name과 boxNum속성을 생략해줍니다. (color는 red로 바꿨습니다.)

 

 

화면의 요소들(컴포넌트)을 만들어보겠습니다.

src경로에서 TestHello.js와 TestBox.js 이렇게 2가지 컴포넌트를 만들어봅니다. 

 

코드 구성은 맨위에 import 리액트선언을 아래와 같이 하고

import React from 'react';

 

function 컴포넌트명(시작문자는 대문자로)으로 생성하여 표현할 태그들을 return해줍니다.

function 컴포넌트명() {
  return (
 
  );
}

사실 태그처럼 보이는 부분은 실제 html태그와는 다른 JSX(Javascript XML)라는 javascript확장문법인데 이 JSX로 작성된 부분이 변환되어 html태그로 보여지게 되는 방식입니다.

return할때 여러줄을 작성하기 위해 ( )로 감싸주며, 작성된 파일은 마지막에 꼭 export선언을 해줍니다.

export default 컴포넌트명;

 

 

이 요소들을 App.js에서 불러보겠습니다.

작성했던 파일js들을 사용할 이름을 지정하여 import해줍니다.

그리고 App함수안에서 지정한 import이름을 xml의 사용자태그처럼 추가해줍니다.

주의할 점은 두 개 이상의 컴포넌트를 넣어줄 때는 <>또는 <div>로 감싸주지 않으면 에러가 납니다.

<div>로 넣을 경우 index파일의 <div id="root">안에 직계로 <div>가 추가되어 그 안에 컴포넌트 태그요소가 출력되며

<>의 경우 <div id="root">하위에 바로 새로 추가한 태그요소가 출력된다는 차이점이 있습니다.

 

 

index화면을 확인해봅니다.

 

TestHello.js와 TestBox.js 컴포넌트 요소가 모두 잘 출력되었습니다.

리액트폴더에서 index파일을 열어보면 body태그안에 태그요소는 <div id="root">요소밖에 별게 없습니다.

(잔뜩있는 영어주석문장들과 noscript요소 제외)

그럼 브라우저에서 보게 되는 index화면의 리액트 아이콘과 텍스트는 어디에서 오는 걸까요?

 

개발자모드를 열어봅니다. 

<div id="root">안에 <div class="App">요소들이 있네요.

 

 

src폴더에 있는 App.js를 열어봅니다.

 

App.js파일안에 아까 개발자모드에 있던 <div class="App">요소들이 담겨 있습니다.

자세히 보면 class이름은 className으로, 이미지경로는 파일 위쪽 import된 경로의 이름을 쓰고있네요.

css파일역시 import를 하고있고요.

이게 리액트를 사용하는 기본적인 방식(의 아주 일부분)인가봅니다.

 

저의 개인적인 리액트 수업내용에 의하면 리액트는 화면에서 보여주는 요소요소를 컴포넌트라는 구성요소단위로 하여

개별 js파일을 만들고 App.js에서 불러들여 index화면에 보여준다고 합니다.

App.js에 대한 내용을 index.html에 랜더링되게 하는 내용은 index.js에 들어있고요.

 

 

각 요소가 정확하게 무슨 역할을 하는지는 모르겠지만 대략적으로 이런식으로 구성되는구나.. 하고 이해하고 넘어갑니다. 

리액트 프로젝트 폴더를 열어보면 3가지 폴더가 보입니다. 각 폴더 안의 파일구성을 살펴보면 다음과 같이 되어있네요.

  • node_modules : react와 서버동작관련 파일
  • public : 이미지, html문서
  • src : css, js, svg파일

 

우선 브라우저화면의 내용을 변경해보기위해 index.html파일을 열어봅니다.

 

흠.. 일단 브라우저 화면의 리액트아이콘 이미지와 텍스트내용이 직접 보이진 않습니다. 화면에서 소스보기를 하면 동일한 내용이 출력되기는 하네요. 그렇다면 어딘가 다른 파일에서 실제 내용을 담고 있다는 말이 되겠죠.

 

찾던 내용은 App.js 이 파일안에 있었습니다. 변경한 내용도 화면에 잘 적용되었네요.

여기서 소스코드와 화면출력코드 상태를 관찰해보면 대략 해당요소들이 어떻게 표현되었는지 발견할 수 있습니다.

import로 불러온 css파일이 어떤형태로 출력되었는지, function App안의 태그요소별 class이름이 어떻게 들어갔는지, svg를 어떻게 사용했는지와 같은 것들이요.

 

 

Cmd나 Powershell, Git Bash같은 콘솔창에서 서버를 실행해도 되지만 VScode콘솔에서도 간단하게 서버를 실행할 수 있습니다.

VScode 상단 메뉴바 Terminal > New Terminal에서 콘솔창을 오픈하고 npm start명령을 입력하면 됩니다.

 

 

콘솔에 다음과 같은 메세지가 나오면서 브라우저 창을 open, 로컬 index.html화면을 보여줍니다.

 

+ Recent posts