하루에 한 챕터도 못하는 날이 많아서 n일차보다는 n번째로 하는게 나을거같네요 리액트가 참 알아야할게 많습니다

 

 

 

React 라이브러리에 무슨 기능이 있는지 보려면~~

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
	<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> 
    <title>Document</title>


</head>
<body>
<script type="text/babel">

        console.log(React)
        
    </script>
</body>
</html>

콘솔을 찍어보면 된다. 

 

 

 

React의 다양한 기능 중에 가장 중요하다고 생각되는 개념 (내 판단)

React Hooks의 대표적인 기능 useState, useEffect, useReducer, useContext 를 간단하게 정리 해보겠습니다

 

먼저 Hooks 가 무엇인지 에 대한 설명.

Hooks는 리액트 16.8에서 새로 도입된 기능으로,
        함수 컴포넌트에서 사용 불가능한 생명주기 메소드의 한계점으로 인해
        상태관리 및 랜더링 이후 시점 컨트롤 등 다양한 문제를 해결하기 위해 만든 함수 집합을 의미한다.


        컴포넌트가 랜더링 된 이후에 특정 작업을 수행할 필요가 있다면
        클래스형 컴포넌트에서는 componentDidMount 혹은 componentDidUpdate 메소드를 이용하면 된다.
        하지만, 함수형 컴포넌트에서는 생명주기 api 사용이 불가능하다. ( 클래스형 컴포넌트에서만 가능했다 )
        그렇기에 함수형 컴포넌트에서도 랜더링 된 이후 시점에 수행할 내용이 필요한 경우
        사용할 수 있게 추가한 hooks 가  useEffect이다.
 
 
 
 

0. props

Props 상위 컴포넌트 하위 컴포넌트에게 데이터를 전달하고자 할 때 사용하는 개념이다. 이때 전달하는 데이터는 하나의 값일수도 있고 함수일수도 있다.

아마도 properties (속성) 의 약자가 아닐까 ??? 

App.js

import React from 'react';
import PropsTest from './PropsTest';

// 상위 컴포넌트 App 에서 하위 컴포넌트 PropsTest 에게 props 전달 중
const App = () => {
  return(
    <>
      <PropsTest name="이대엽" /> 
    </>
  );
};

export default App;

 

PropsTest.js

import React from "react";

const PropsTest = ({ name }) => {
  return <h2>{name}님 어서오세요!</h2>;
};

export default PropsTest;

PropsTest.js는 상위 컴포넌트인 App.js로 부터 name값을 전달 받아 사용하고 있다.

 

 

1. useState

State란 컴포넌트 내부에서 가지고 있는 해당 컴포넌트의 상태 값들을 의미한다.

 

 사용 형태

// 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수

const [ 변수 , set변수 ] = useState(변수의 초기값)

 

const [ count , setCount ] = useState( 0 )

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
     <!-- 버전은 명시 상관x    standalone 가능 -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> 
    <title>Document</title>


</head>
<body>
    <div id="root"></div>
    함수형 컴포넌트 에서는 state를 사용할 수 없었음. 

    <script type="text/babel">
        
        const {useState} = React;

        // const Say = () => {}
        function Say() {
            
            console.log(useState('기본상태'));
            let val = 0;  // 상태값이 하나라도 바뀌면 Say 컴포넌트가 새로 렌더링 되면서 계속 0으로 초기화 됨
            // 배열로 반환됨, 
            // 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수
            const [message , setMessage] = useState('기본상태')

            const onClickEnter = () => setMessage('하이요')  // onClick에 걸어줄 함수
            const onClickLeave = () => setMessage('바이요')  // onClick에 걸어줄 함수

            // 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수
            const [color , setColor] = useState('black')

            // 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수
            const [backgroundColor, setBackgroundColor] = useState('white')

            // style 안에있는 color, backgroundColor 변수가, 위에 useState로 만든 상태값 저장 변수 !!
            return(
                <>
                    <h1 style = {{color, backgroundColor}}>{message}</h1>
                    <button onClick={onClickEnter}>입장</button>
                    <button onClick={onClickLeave}>퇴장</button>
                    <button onClick={()=>{
                        val = val + 1;
                        console.log(`지역변수 업데이트 : ${val}`);
                    }}>지역변수</button>
                    <div>
                        <button onClick= {() =>setColor('red') }>빨간색</button>    
                        <button onClick= {() =>setColor('purple') }>보라색</button>    
                        <button onClick= {() =>setColor('green') }>초록색</button>    
                    </div>
                    <div>
                        <button onClick= {() =>setBackgroundColor('white') }>기본배경</button>    
                        <button onClick= {() =>setBackgroundColor('black') }>반전배경</button>    
                    </div>                        
                
                </>
                
            );
        }

        ReactDOM.render( <Say/> , document.getElementById('root'));
        
    </script>
</body>
</html>

html 파일로 만들어서 쌩으로 실행이 가능한 코드입니다.

 

▲실행 결과 사진

 

 

input 창의 value 를 useState로 저장하는 방법

UseStateTest.js     ( App.js 는 생략 )

import React, { useState } from "react";

const UseStateTest = () => {
  
  const [name, setName] = useState('');
  const onChange = (e) => {
    setName(e.target.value);
  };

  return (
    <>
      <input onChange={onChange} />
      <h1>제 이름은 {name}입니다.</h1>
    </>
  );
};

export default UseStateTest;

onChange 함수에서 매개변수로 사용된 e 는 event 의 약자이며 , 로그를 찍어보면 

 

 

 

 

 

e 가 좀 괴상하게 생기긴 했는데, e에 있는 target 속성을 열어보면 input이 있는걸 확인할 수 있다.

 

 

 

onChange 가 될 때 마다, setName 함수가 호출될 것이고          그 말은 곧 ,

input 에 입력하는값이 즉시 name 상태 저장 변수로 저장된다.

 

 

2. useEffeft

useEffect란 컴포넌트가 조건에따라 렌더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook 이다.

useEffect(()=> {
  // 실행하고자 하는 함수
  () => { 
  
  }
}, []);

 

 

 

1. 컴포넌트가 렌더링 될 때 마다 (의존성 배열 생략) ,

 

2. 최초 렌더링 시 한 번만 (의존성 배열에 공백),       (최초 렌더링 = 마운트 되다)

 

3. 특정 변수의 상태가 변할 때만 (의존성 배열에 상태 변수 명시),

용어 설명 !!! ->    deps : dependency (의존성)

useEffect 내에서 사용하는 State나 Props가 존재한다면, useEffect의 deps에 넣어주는 것이 규칙이다. 만약 넣어주지 않는 다면 useEffect 내의 함수가 실행될 때 최신 State, Props를 가리키지 않는다는 문제점이 생긴다!

 

4. 컴포넌트가 사라질 때, 특정 값이 바뀌기 직전에 (useEffect 안에 return 함수 (clean-up) )

 

Timer 컴포넌트

토글 버튼을 눌러서 1초마다 한번 씩 현재시간을 log에 출력하거나, 출력을 그만두는 기능.

 

 

특정값이 업데이트 되기 직전에 cleanup 함수를 사용하고 싶다면  deps(의존성배열) 안에 감지하고 싶은 값을 넣어주면 된다. (사진은 없다)

 

Timer 컴포넌트를 하위컴포넌트로 렌더링 시키는 중인 App.js 

 

 

 

 

컴포넌트가 사라질 때, 수행되는 함수(clean-up) 라서 뒷정리 함수라는 이름으로도 불린다. 

 

 

 

3. useReducer

useReducer 란 다양한 컴포넌트의 state를 일괄적으로 업데이트 할 때 사용하는 Hook 이다.

리듀서는 새로운 상태를 만들 때 반드시 불변성을 지켜주어야 한다. (기존 state의 값 변경 하지 말고 새롭게 만들 것)
리듀서를 사용했을 때 가장 큰 장점은 컴포넌트 업데이트 로직을 컴포넌트 밖으로 분리할 수 있다는 점이다.

 

react의 심오한 기술중 하나인 redux 에서 핵심 역할을 하는 함수이기도 하다.
너무 어려워서  나도 글과 말로 설명할 자신이 없다. ㄱ ㅡ
 
 Counter 컴포넌트
 
컴포넌트 바깥에 정의된 reducer 함수
 

1. 상태의 변화는 dispatch 의 호출에 의해서만 일어난다. 

2. dispatch 의 매개변수는

업데이트를 하기 위해 필요한 정보 객체  { type : 'INCREMENT' } , { type: 'DECREMENT' }

 = reducer 함수의 두 번째 인자로 들어가게 됨

 

이다. 

3. reducer 함수에서만 실질적인 값의 변화가 일어난다. (새로운 상태값이 반환 된다.)

 

 

value의 증가 감소의 상태 관리를 reducer 함수에서 모두 관리하고 있다. 

하나의 함수에서 상태관리를 하는것이 reducer의 장점.

 

 

 

4. useContext

Context 란?

React 공식 문서에 쓰여있는 설명에는, ' context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다 ' 라고 적혀있다.

 

 

일반적인 React 어플리케이션에서 데이터는 props를 통해서 부모에서 자식에게 전달 되어야 한다.

  Parent.js

 

Child.js

Parent 의 return 부분에서 컴포넌트 렌더링부분에 number={number} 라는 속성(props) 을 추가하여 컴포넌트간에 변수를 공유 할 수있다.

 

 

 

자식에서 부모로 전달되는 경우도 있긴 하지만, 구조가 기구하다.

부모에서 만든 함수를 자식에게 부여해서,

자식에서 그 함수를 이용하여 상태를 변화시키고 

부모가 변화를 감지하여 렌더링 하는 방식이다 .

 

    Parent.js

 

   Child.js

 

부모에서 만든 함수(  getData(number) )        를 자식에게 부여해서,   (   <Child getData={getData} ></Child>  }

자식에서 그 함수를 이용하여 상태를 변화시키고         (  onClick 에서 getData 함수 사용중  -> 상태 변화 됨 )

부모가 변화를 감지하여 렌더링 하는 방식이다 .

 

 

 

컴포넌트가 많아지면 많아질수록 , 이렇게 일일이 props 를 전달하기에는 현실적으로 무리...

 에휴 

 

그래서 사용하는것이 useContext.

 

어플리케이션 안의 여러 컴포넌트들에게 props를 전달해줘야 하는 경우

useContext를 이용하면 명시적으로 props를 넘겨주지 않아도 값을 공유할 수 있게 해준다.

 

 

<script type="text/babel">
        /*   context는 React컴포넌트 트리 안에서 전역적으로 데이터를 공유할 수 있도록 고안된 방법이다. 
         * 트리 구조가 복잡해질 수록 하위 컴포넌트로 props를 전달하기 위해 drilling  이 발생할 수 있게 되고,
         * 그러면 유지보수가 매우 힘들어지고 코드를 읽기도 힘들어지게 된다.
         * 하지만 context를 사용하면 중간 엘리먼트들에게 props를 넘겨주지 않아도 되고, 유지보수도 훨씬 수월해지게 된다.
         * 
         * 단, context를 사용하면 컴포넌트를 재사용하기 어려워지기 때문에 꼭 필요할 때만 써야 한다.
         * 따라서 때에 따라서는 context보다 컴포넌트 합성이 더 간단한 해결책일 수 있다.
         */
        const {useState, createContext, useContext} = React;

        // 주의 : 첫글자 대문자로 해야함
        const DarkModeContext = createContext(null);
        const UserContext = createContext(null);

        function Header() {
            // 사용이 필요한 곳에서 꺼내서 쓴다 >?
            const context = useContext(DarkModeContext);

            const {isDark} = context;

            return (
                <header className="header"
                style = {{
                    backgroundColor:  isDark ? 'black' : 'lightgray' ,
                    color : isDark? 'white' : 'black'
                }}>
                    <h1>어서오세요 헤더입니다</h1>
                </header>
            )
        }

        function Content() {
            // 사용이 필요한 곳에서 꺼내서 쓴다 >?
            const context = useContext(DarkModeContext);
            const userContext = useContext(UserContext);

            const {isDark} = context;
            const {username, setUsername} = userContext;
            setUsername('이대엽'); // 바로 실행이 되긴되네요

            return (
                <div className="content"
                style = {{
                    backgroundColor:  isDark ? 'black' : 'white' ,
                    color : isDark? 'white' : 'black'
                }}>
                    <p>콘텐츠 입니다<br/></p>
                    <p>{username}님 안녕하세요 ?</p>
                </div>
            )
        }

        function Footer() {
            // 사용이 필요한 곳에서 꺼내서 쓴다 >?
            const context = useContext(DarkModeContext);

            const {isDark, setIsDark} = context;
            const toggleHandler = () => {
                setIsDark(!isDark);
            }

            return (
                <footer className="footer"
                style = {{
                    backgroundColor:  isDark ? 'black' : 'lightgray' ,
                    color : isDark? 'white' : 'black'
                }}>
                    <button onClick={toggleHandler}>{isDark? '다크모드 해제' : '다크모드 전환!!' }</button>
                    우리집은 대한민국 부산시
                </footer>
            )
        }

        function Page({isDark, setIsDark}) {
            return (
                <div className="page">
                    <Header />
                    <Content />
                    <Footer />
                </div>
            )
        }

        // <Header isDark={isDark}/>
        // <Content isDark={isDark}/>
        // <Footer isDark={isDark} setIsDark={setIsDark}/>
        
        function App() {
            // App 에서 만든 setState 를 다른 컴포넌트한테 계속 넘겨주면서 사용할 수 있구나 
            const [isDark, setIsDark] = useState(false)
            const [username, setUsername] = useState('유재석')


            /* Provider는 context를 구독하고 있는 컴포넌트들에게 context의 변화를 알리는 역할을 한다.
             * Provider(제공자)는 value props을 이용하여 하위 컴포넌트에게 값을 전달한다.
             * 이 때 값을 전달받을 수 있는 컴포넌트 수에는 제한이 없다.
             * 
             * Provider 하위에서 context를 구독하는 모든 컴포넌트는 value prop이 바뀔 때 마다 다시 랜더링된다.
             *  즉 isDark 가 바뀌면 전체리랜더링
             * */


            return (
                // <Page isDark = {isDark} setIsDark = {setIsDark}/>
                // 하위 컴포넌트 들에서도 사용이 가능하다 
                <UserContext.Provider value = {{username, setUsername}}>
                    <DarkModeContext.Provider value = {{isDark, setIsDark}}>
                        <Page/>
                    </DarkModeContext.Provider>
                </UserContext.Provider>
            )
            
        }
        

        ReactDOM.render(<App/>, document.getElementById('root'));
    </script>

최상단에서 createContext 를 하고,  컴포넌트의 부모위치에서 Context.Provider 로 공유받을 수 있게 설정 하고.

각각의 컴포넌트에서도 따로 선언하여 사용하는 방식이다.

 

설명이 짧아서 미안하다

나  많은일이 있었다  힘들다 진짜

'더존 노션 필기 옮기기 > React' 카테고리의 다른 글

React 비상사태  (0) 2022.09.08
React 1일차 컴포넌트 ,JSX , props  (0) 2022.09.08

이 라이브러리의 업데이트가 너무 잦아서

옛날자료(정보 양이 많긴 함) + 현대자료(정보가 적음, 공식문서는 영어임) 들의 충돌이 너무많다

 

 

일단 할 수 있는 것과 할 수 없는 것의 구분부터 시작해야 할 것 같다.

 

 

 

리액트 컴포넌트의 역사

// * 첫 번째 인자는 만들려는 엘리먼트의 타입을 문자열로 정의한다.
// * 두 번째 인자는 만드는 엘리먼트의 프로퍼티를 표현한다.
// * 세 번째 인자는 엘리먼트의 자식 노드(텍스트노드)를 표현한다.

const greetingElement = React.createElement('h1', {id : "greeding1" } , 'hello world');

// 결과 
<h1 id="greeding1"> hello world </h1> 
라는 Element ( 리액트 에서는 일반적으로 컴포넌트 라는 개념으로 더 많이 알려져있다. )
가 생성된다.

옛날에는 정말 엿같은 방식으로 컴포넌트를 만들고 있었네요

그 이후에도 몇 가지 방법들이 추가가 되었지만

createClass 함수
클래스형 컴포넌트

리액트 16버전 이후로는 ‘함수형 컴포넌트’ 를 주로 사용하고 있습니다.

function Hellowolrd() {
            return React.createElement(
                    'h1',
                    {className : 'greeting'},
                    'Hello world!'
                );
        }
                                    // 함수 이름
ReactDOM.render(React.createElement(Hellowolrd) , document.getElementById('root'));

뭐지 정리해보고나니까 달라진게 없는데요 ??? ??????????????????   (바벨을 아직 적용 안해서)

 

바벨 이라는 문법 변환 도구를 적용 한 뒤, ( 밑에 JSX 내용을 보고 오면 더 좋음 )

function Title2() {                        // 1. 함수 만들어 (첫글자 대문자 !!)
    return(                                 // 2. 리턴 만들어
        <h1>함수형 컴포넌트</h1>            // 3. JSX 엘리먼트 만들어
    );
 }

 ReactDOM.render(<Title2/>, document.getElementById('root'));

ReactDOM.render(element, container) 인자(args) 정리

element = 내가 만든 DOM

container = 어느 노드에 넣을지 (그 노드가 부모가 되고, 내가 만든 DOM은 자식이 된다 )

JSX가 무엇인가

JS (JavaScript) + XML 로써 자바스크립트를 확장한 문법이라고 설명하겠습니다.

위에서 설명한 컴포넌트 작성 방법을 조금ㄷ ㅓ~~~ 깔끔하게 도와주는 문법입니다.

JSX 는 공식적인 자바스크립트 문법이 아니기 때문에 바벨(babel) 이라는 문법 변환 도구가 필요합니다.

이는 문서 맨 윗 단에 CDN 한 줄을 추가 해주시면 됩니다

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

JSX 문법 (스타일 관련은 그냥 거르세요 중요X)

xml 문법- 반드시 닫기 태그 와 함께 사용
        ex) <key>value</key>
        ex) <key/>--셀프클로징(자식노드에 값이없을때)
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

렌더링 할 요소는 최상위 엘리먼트 하나 만 있어야한다.
// const element = (<h1> Hello, {user.name} </h1> 
//                 <h3> Hello, {user.phone} </h3>); // 불가능

// 하나의 돔 트리로 만들면 가능
// const element = (
//     <div>
//         <h1> Hello, {user.name} </h1> 
//         <h3> Hello, {user.phone} </h3>
//     </div>    ); // 가능

// <React.Fragment>로 감싸서 형식상의 돔트리상 상위 엘리먼트를 만들어준다.
//     React 16 버전에서 추가 된 기능으로 별도의 노드를 추가하지않고 여러자식을 그룹화한다.
//     위의 div와 같이 불필요한 DOM node 생성을 막기 때문에 메모리를 적게 사용한다
// const element = (
//     <React.Fragment>
//          <h1> Hello, {user.name} </h1> 
//          <h3> Hello, {user.phone} </h3>
//     </React.Fragment>
// )

// React.Fragment 의 축약 문법 ( 그냥 아무것도 안써도 됨)
const element =(
    <>
        <h1> Hello, {user.name} </h1> 
        <h3> Hello, {user.phone} </h3>
    </>
);

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
속성값(Attribute) 적용방법

JSX는 html 태그처럼 보이지만 실제로는 자바스크립트이다. 
(React.createElement를 호출하는 코드로 컴파일된다.)
따라서 자바스크립트의 예약어와 동일한 이름의 attribute는 
다른 이름으로 우회적으로 사용하도록 정의되어 있다.

// const element = (
//     <div>
//         <h1> Hello, {user.name} </h1> 
//         <h3> Hello, {user.phone} </h3>
//     </div>    );
즉 작성은 이렇게 하지만 바벨로 변환하고 나면 실제 실행은 위에 봤던 엿같은 코드로 실행된다는 
이야기.

// 1. 문자열로 속성값 정리하는 방법
// const element = <h1 id="title" className="light"> Hello world~</h1>;

// 2. JavaScript 표현식 ({}) 을 이용하여 정의하는 방법
const id = "title";
const className = "light"

const element = <h1 id= {id} className = {className}> Hello world~</h1>;

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

컴포넌트에 스타일 적용하기 ( 내부 )
/* 스타일을 적용하기 위한 객체의 속성명은 카멜케이스로 작성해야 한다.
*  예) background-color -> backgroundColor 
*  속성값은 문자열 혹은 숫자 형태로 작성해야 한다.
* */
// 스타일 객체
const styleVal = {
    backgroundColor : 'black',
    color : 'white',
    cursor : 'pointer',
    textAlign : 'center',
    padding : 20
}

const element = (
    <>          // 객체 때려박기
        <h1 style = {styleVal}> Hello world</h1>
        <h3> inline styling test</h3>
    </>
);

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

이벤트 처리하기

// 1. 인라인으로 간단한 이벤트 적용 시 JSX의 자바 스크립트 표현식 내에 이벤트처리 함수 작성
// const element = (
//     <>
//         <h1> Event Attribute</h1>
//         <button onClick = {function(){alert('Hello world')}}> 클릭하세요</button>
//         <button onClick = {() => alert('Hello arrow world')}> 클릭하세요</button>
//     </>
// )

// 2. 이벤트 동작 시 사용할 핸들러 메소드를 사전 정의 후 JSX 내에 표현식으로 사용
const onClickHandler = () => {
alert('Hello');
}

const onClickHandler2 = function (){
alert('Hello2');
}

const element = (
<>
    <h1> Event Attribute</h1>
    <button onClick= {onClickHandler2}> 클릭하세요 핸들러 </button>
</>
)

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
조건부 렌더링 ( if문 사용 불가 )
아직 정확한 조건은 모르겠지만 JSX 에서 IF 문 사용을 권장하지 않는것 같다.
어디에선 써지고 어디에선 안써진다...
그래서 이러한 방법으로 조건을 확인 할 수 있다.
1. 삼항연산자 (아니깐 패스)

2. && 문법
true만 확인 할 수 있는 조건문 이다. 
1 == 1 && <p> 트루입니다 !</p> 

3. 즉시발동함수  https://myhappyman.tistory.com/60
const word = 'react';
  return (
    <div>
    {
      (function(){
        if(word == 'react'){
          return ("리액트!")
        }else if(word == 'hello'){
          return ("헬로우!")
        }else if(word == 'world'){
          return ("월드!")
        }
      })()
    }
    </div>
  );

3.1 즉시발동함수 화살표함수
(()=>{
      if(word == 'react'){
        return ("리액트!")
			}
		})
 
 

JSX 문법으로 위에서 만든 컴포넌트랑 똑같은 컴포넌트를 만들어보겠습니다.

<script type = "text/babel">
	  const helloworld = <h1> hello world </h1>;
	
	  ReactDOM.render(helloworld, document.getElementById('root'));

</script>

helloworld 변수에 HTML 코드를 냅다 넣고있는데 오류가 없습니다.

컴포넌트 합성

const user = {
             name: '홍길동',
             age: 20,
             phone: '010-1234-5678',
             email: 'hong123@gmail.com'
         }
        
         function NameCard() {
            return <h1>{user.name}</h1>
         }
         function AgeCard() {
            return <h1>{user.age}</h1>
         }
         function PhoneCard() {
            return <h1>{user.phone}</h1>
         }
         function EmailCard() {
            return <h1>{user.email}</h1>
         }

         // 각각의 컴포넌트 들을 감싸는 컴포넌트
         function UserInfo() {
            return (<div style={{width:300 , border: '1px solid black'}}>
                <NameCard/>    
                <AgeCard/>    
                <PhoneCard/>    
                <EmailCard/>    
            </div>);            
         }
        

        ReactDOM.render(<UserInfo/>, document.getElementById('root'));

배우진 않았지만 State 혼자 정리

State (상태)는 컴포넌트가 갖고있는 속성값 입니다. 이 속성값이 변하면 리액트 엔진은 자동으로 UI를 업데이트 시켜줍니다.

state 실습예제를 하려면 import 가 필요한데 예제를 전부 html 에서 해서 ㅠㅠ

나중에 추가하겠습니다.

props

properties의 약어로, 컴포넌트의 속성을 설정할 때 사용하는 요소이다.

부모에게 받아온 데이터입니다.

리액트의 Data Flow는 단방향 형식으로 부모에서부터 자식으로 이동하기 때문에 거꾸로 올라갈 수 없습니다.

따라서 props에 있는 데이터들은 수정이 불가능하며 오직 안에있는 값을 꺼내서 사용할수만 있습니다.

 

>> 라고 처음엔 생각했지만 ? useState 의 기능으로 상태값 관리를 하게된다면 말이 달라질지도 ...

props 기본 렌더링

const name1 = '이대엽';
const name2 = 'dleoduq';

// 2. xxx 에 name1 을 전달해서 표현    매개변수에 props, state 라고 적어주는게 
// 규칙 이라는듯 !?

function Title2(props) {
    console.log(props);
    return <h1> 안녕하세요 {props.name} 님~! </h1>
}

ReactDOM.render(
    <Title2 name = {name1}/>, document.getElementById('root')
);

자바스크립트로 선언된 변수를 JSX 에서 쓰고싶다면,

{ 변수이름 } 중괄호를 씌워주면 된다.

자식노드 렌더링

자식 노드를 전달하는 props.children 리액트 컴포넌트를 사용할 때 태그 사이의 내용을 props의 children 속성에서 관리한다.

function ChildNodePrinter(props) {
    console.log(props);
    return (
        <>
        <h1>자식노드가 가지고 있는 값은</h1>
        <h3>Children : <font style={{color : 'orange'}}>{props.children}</font> </h3>
        </>
    )
}

ReactDOM.render(
[
    <ChildNodePrinter>텍스트노드</ChildNodePrinter>,
    <ChildNodePrinter><div>자식노드</div></ChildNodePrinter>,
    <ChildNodePrinter><div>1</div><div>2</div><div>3</div></ChildNodePrinter>

],
document.getElementById('root')
)

결과 >>

 

props 구조분해할당 https://youtu.be/lV7ulA7R5Nk?t=178

구조분해할당 : 배열이나 객체의 속성을 구분해서 그 값을 변수에 담을 수 있게 하는 표현식

중괄호로 감싼 변수로 제시한 속성 {name, children} 에

props 객체의 속성과 이름이 일치하면, 그 값을 부여하는 기능입니다.

 

const {name, children} = props; 는 아래와 같다
        const name = props.name;
        const children = props.children;

 

리액트를 이래저래 다루다 보니 알게모르게 배열 구조분해할당, 객체 구조분해할당을 굉장히 많이 사용하고 있길래

제 생각엔 절대 모르면 안될 내용일 것 같습니다.

 

// 전달 받는 인자를 바로 비구조화 할당
function PropsPrinter(props) {
    // 비구조화 할당을 하게 되면 공통적으로 사용하는 props.을 생략하고 사용할 수 있다.
    console.log(props);  // {name: 'dleoduq', children: '문자열자식'}  객체 타입이다
    const {name, children} = props;
    /*
    	const {name, children} = props; 는 아래와 같다
        const name = props.name;
        const children = props.children;
    */

    return (
        <>
            <h1>제이름은 {name} 입니다</h1>
            <h3>제가 가지고있는 자식은 {children} 입니다</h3>
        </>
    )
}

ReactDOM.render(<PropsPrinter name = "dleoduq" children = "문자열자식"/>
, document.getElementById('root'));

props 에 전달되는 타입 검증

근데 콘솔에서만 오류를 알려주던데 어떻게 사용하는걸까 ?? - 고민해결되면 수정할 것 ( 아니 수정안할거< <이게 수정임)

propTypes 를 이용하기 위해 CDN 추가
function PropsVerify({name, favoriteNumber, children}) {
    return (
        <>
            <h1>제이름은 {name}</h1>
            <h1>제가 가잫 좋아하는 숫자는 {favoriteNumber}</h1>
            <h1>제가 가지고있는 children은 {children}</h1>
        </>

    )
}
// 문법
PropsVerify.propTypes = {
    name : PropTypes.string,         // 문자열인지 검증
    favoriteNumber : PropTypes.number.isRequired   // 숫자형인지 검증, 값을 입력했는지 검증

}

ReactDOM.render(
    [
        <PropsVerify name="이대엽" favoriteNumber={5}>텍스트노드</PropsVerify>,
        <PropsVerify name="이대엽" favoriteNumber={5}>자식 텍스트노드</PropsVerify>,
        /*중괄호 씌우면 숫자*/
        <PropsVerify name={3}  favoriteNumber={5}>자식 텍스트노드</PropsVerify>,  // name string 무시
        <PropsVerify name="이대엽3" >자식 텍스트노드</PropsVerify>   // isRequired 무시
    ]
    , document.getElementById('root'));

+ Recent posts