Front-end/React

[코딩애플] #1 React 기초

성중 2021. 7. 20. 20:28

React를 왜 쓸까?

설치 및 셋팅

  • ‘npx create-react-app (앱 이름)’: 리액트 프로젝트 생성
  • ‘npm start’: 실행 결과 미리보기 (Ctrl + C -> 서버 종료)
  • js파일 상단에 /* eslint-disable */ 을 추가해 warning 제거

 

  • App.js 파일: 메인 페이지(index.html)에 들어갈 HTML 짜는 곳
  • node_modules 폴더: React 구동에 필요한 라이브러리들을 모아 놓은 폴더
  • public 폴더: 동적으로 바뀌지 않는 static 파일 보관함
  • src 폴더: 실질적으로 개발하는 소스코드를 모아 놓은 폴더

 

JSX 사용법

 App.js 파일 function App() 내부에 HTML처럼 생긴 JSX로 코딩할 수 있다

서버에서 데이터를 받아와 변수로 저장하고 HTML 상에 띄우는 데이터 바인딩이 용이하다

 

{ 변수명, 함수 등 } -> 중괄호 안에 넣으면 HTML 상에 출력된다
style={ object 자료형으로 만든 스타일 } -> style을 JSX에서 바로 적용할 수도 있다

*CSS 속성이름은 Camel case로 바꿔야 하고, 스타일 object를 변수에 저장해 불러올 수도 있다

 

useState

 React는 데이터를 변수 말고 state에 넣을 수 있다.

~ useState를 import해오고 useState( ); 함수로 사용 (2개의 데이터가 들어간 Array 형태)

 

ES6 destructuring 문법으로 useState object의 자료를 변수에 담아준다

  let [a,b] = useState('안녕하세요');

[a,b]에 [state 데이터, state 데이터 변경 함수]가 각각 담긴다

  let [글제목,글제목변경] = useState('안녕하세요');

useState 안에 Array로 저장해 가져오는 것도 가능

 let [글제목, 글제목변경] = useState(['첫 글', '두 번째 글']);

        <h3>{ 글제목[0] }</h3>

state가 변경된다면 새로고침 없이 HTML이 자동으로 재렌더링된다

~ 자주 바뀌는, 중요한 데이터는 변수 말고 state로 저장해서 쓰자!

 

버튼에 이벤트 리스너 넣기

 원하는 태그에 onClick={클릭될 때 실행할 함수()}를 달아준다

함수를 따로 정의하기 싫다면 onClick={ ()=>{실행할 내용} } 이런 식으로 쓸 수 있다

 

state 값을 변경시키려면 state 데이터 변경 함수를 활용해야 한다

  let [따봉, 따봉변경] = useState(0);

span을 클릭할 때마다 state 값을 1씩 증가시켜보자

        <h3>{ 글제목[0] } <span onClick={ ()=>{} }>👍</span> { 따봉 }</h3>

예를 들어 이렇게 쓰면 state 값(따봉)이 10이 된다

  따봉변경(10);

state 변경함수 안에서 state 값을 가져와 변경할 수도 있다

        <h3>{ 글제목[0] } <span onClick={ ()=>{따봉변경(따봉+1)} }>👍</span> { 따봉 }</h3>

state 변경하기

 state 배열을 직접 가져와서 바꿀 수 있다 (하드코딩)

  function 제목바꾸기 () {
    글제목변경(['제목이 바뀜', '두 번째 글', '세번쨰']);
  }
       <button onClick={ ()=>{제목바꾸기()} }>버튼</button>

함수가 길어지면 따로 빼서 정의한 후 넣어 주기

 

배열의 특정 state를 다루려면 대충 이런 느낌으로 변수를 빼야 한다

  function 제목바꾸기 () {
    var newArray = 글 제목에 있던 0번째 데이터를 바꿈
    글제목변경(newArray);
  }

state의 복사본을 만들어 한 다리 걸쳐서 변경해줘야 한다

단, 그냥 복사가 아니라 이런 식으로 deep copy를 해줘야 하는데,,

let [글제목, 글제목변경] = useState(['첫 글', '두 번째 글', '세번쨰']);

  function 제목바꾸기 () {
    var newArray = [...글제목];
    newArray[0] = '글 제목 변경';
    글제목변경(newArray);
  }

deep copy는 값을 공유하는 것이 아니라 서로 독립적인 값을 가지는 복사이다

 

Component로 HTML 깔끔하게 줄이기

 반복적으로 쓰이거나 자주 변경되는 UI, 다른 페이지를 만들 때는 Component로 만들어주자!

 

그냥 function을 따로 만들어서

function Modal(){
  return(
    <div className="modal">
        <h2>제목</h2>
        <p>날짜</p>
        <p>상세내용</p>
      </div>
  )
}

이렇게 App function 원하는 위치에 넣어주면 된다

      <Modal />

* Component 이름은 대문자로 시작해야 하고 return() 안의 요소는 하나의 태그로 묶여야 한다

 

삼항연산자

UI (모달창)이 클릭하면 띄워지도록 해보자

JSX에는 if문을 쓸 수 없기 때문에 중괄호 안에 삼항연산자를 넣어 줄 것이다

      { 
         modal === true 
         ? <Modal></Modal>
         : null
      }

modal 값이 true이면 modal 창을 띄우고 아니라면 null 값을 반환

 

modal 값을 제어할 수 있는 useState를 정의해주고,,

  let [modal, modal변경] = useState(false);

특정 요소를 클릭할 때 modal 창을 열고 닫으려면,,

function App (){

  let [modal, modal변경] = useState(false);
  return (
    <div>

      <button onClick={ ()=>{ modal변경(!modal) } }> 열고닫는버튼 </button>
      { 
         modal === true 
         ? <Modal />
         : null
      }
    </div>
  )
}

이런 방식으로 React에서는 UI를 열고 닫는다!

 

map/for

리액트에서는 HTML도 반복문으로 반복시켜 줄일 수 있다

 

.map() 함수를 array 내의 모든 데이터에 함수를 한 번씩 적용하는 유사 반복문으로 쓸 수 있다

이런 식으로 array 데이터와 html을 순회시킬 수 있다 (바깥 중괄호 필수)

* a는 배열에서 순서대로 가져오는 데이터, i는 순회 할 때마다 1씩 증가하는 값이다!

          {
            shoes.map((a,i)=>{
              return(
                  <Card shoes={shoes[i]}></Card>
              )
            })
          }

일반적인 for 반복문은 함수를 통해 사용할 수 있다

function App (){

  function 반복된UI(){
    var 어레이 = [];
    for (var i = 0; i < 3; i++) {
      어레이.push(<div>안녕</div>)
    }
    return 어레이
  }
  return (
    <div>
      HTML 잔뜩있는 곳
      
      { 반복된UI() }
    </div>
  )
}

props

Modal 창(자식 컴포넌트)에 App(부모 컴포넌트)의 state 데이터를 넣어보자

즉, 부모 컴포넌트의 state 데이터를 자식 컴포넌트에 props로 가져다 쓰려면,,

function App (){
  let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
  return (
    <div>
      ...
      <Modal 글제목={글제목}></Modal>
    </div>
  )
}

function Modal(props){
  return (
    <div className="modal">
      <h2>제목 { props.글제목[0] }</h2>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}
  1. <자식컴포넌트 전송할이름={state명}> 이라고 정의한 후
  2. function Modal(props){} 이렇게 Modal 함수 소괄호 내에 파라미터를 하나 추가
  3. props.전송할이름 이렇게 전송된 props를 사용

* props는 <Modal 이런거={이런거}  저런거={저런거}> 이렇게 10개 100개 1000개 무한히 전송이 가능

* 애초에 특정 state 배열만 props로 전달할 수도 있다

          <Card shoes={shoes[0]}></Card>
          <Card shoes={shoes[1]}></Card>
          <Card shoes={shoes[2]}></Card>

UI 제작 패턴

Modal창의 props를 활용해 상세 UI를 구성하려면,,

  1. UI와 관련된 중요 정보들을 state로 저장해놓고
  2. state에 따라서 UI가 수정되게 만들면 된다

예를 들어 배열 숫자로 제목을 변경하려면,,

  let [누른제목, 누른제목변경] = useState(0);

배열 숫자를 변경할 변수를 state로 선언하고

      { 
         modal === true 
         ? <Modal 글제목={글제목} 누른제목={누른제목} ></Modal>
         : null
      }

props로 전송하고

        <h2>{ props.글제목[props.누른제목] }</h2>

배열 번호에 변수로 넣어준다

      <button onClick={ ()=>{누른제목변경(0)} }>버튼1</button>
      <button onClick={ ()=>{누른제목변경(1)} }>버튼2</button>
      <button onClick={ ()=>{누른제목변경(2)} }>버튼3</button>

상세 내용을 state 변경함수로 자유롭게 제어할 수 있다!

 

변수 i를 활용해 map으로 순회하는 html 태그에 변경함수를 적용하자 (key={i}는 없어도 ㄱㅊ)

      {
        글제목.map(function(글, i){
          return (
            <div className="list" key={i}>
              <h3 onClick={ ()=>{누른제목변경(i)}}>{ 글 } <span onClick={ ()=>{따봉변경(따봉+1)} }>👍</span> { 따봉 }</h3>
              <p>7월 19일 발행</p>
              <hr/>
            </div>
          )
        })
      }

input 다루기

사용자가 input으로 입력한 글을 변수에 저장해보자

      <input onChange={ (e)=>{ e.target.value } }></input>

onChange는 input에 값이 입력될 때마다 함수를 실행한다

e.target.value현재 input에 입력된 값을 반환한다

  let [입력값, 입력값변경] = useState('');
  
        <input onChange={ (e)=>{ 입력값변경(e.target.value) } }></input>

state 데이터 변경 함수로 입력된 값을 state 변수로 저장할 수 있다

 

array 사본을 통해 해당 변수를 글제목 state에 추가하는 함수를 짜보자 (unshift()는 array 맨 앞에 자료를 추가해준다!)

function App (){
  let [글제목, 글제목변경] = useState(['남자코트추천', '강남우동맛집', '파이썬독학']);
  let [입력값, 입력값변경] = useState('');
  return (
    <div>
      HTML 잔뜩 있는 곳
      <div className="publish">
        <input onChange={ (e)=>{ 입력값변경(e.target.value) } } />
        <button onClick={ ()=>{ 

          let arrayCopy = [...글제목];
          arrayCopy.unshift(입력값);
          글제목변경( arrayCopy )

         }}>저장</button>
      </div>
    </div>
  )
}

 

실전에서도 이런 방식으로 입력한 state 값을 서버로 보내 저장한다!

 

본 내용은 코딩애플의 '리액트 기초부터 쇼핑몰 프로젝트까지!'를 바탕으로 작성되었습니다.