KDT/TIL

9/28 TIL : props, 컴포넌트 꾸미기(inline, sass, styled-components), useRef

ebulsok 2022. 9. 28. 18:35

실습: 카운터 만들기

  • 최상단에 태그로 0 인 숫자가 있고, 아래에는 +1, -1 이라는 버튼
  • +1 버튼을 누르면 숫자가 +1 이 되고, -1 버튼을 누르면 숫자가 -1 이 되도록
import React, { useState } from 'react';

export default function Counter() {
    const [count, setCount] = useState(0);
    const onInc = () => { setCount(count + 1) };
    const onDec = () => { setCount(count - 1) };

    return (
        <div>
            <h1>{count}</h1>
            <button onClick={onInc}>+1</button>
            <button onClick={onDec}>-1</button>
        </div>
    )
}

 

🔎 props

  • 리액트에서 백엔드의 데이터를 프론트로 전달하는 방식
  • html의 속성을 부여하는 것처럼 props명전달하고자 하는 데이터를 적기
// App.js
	<MainHeader text="Hello, props world!" name="ebulsok" />
import React from 'react';

function MainHeader(props) {
    return (
        <div>
            <h1>{props.text}</h1>
            <h1>{props.name}</h1>
        </div>
    )
}

// 구조분해할당
// function MainHeader(props) {
//     const { text, name } = props;
//     return (
//         <div>
//             <h1>{text}</h1>
//             <h1>{name}</h1>
//         </div>
//     )
// }

export default MainHeader;

 

🚩 클래스형 컴포넌트에서의 props: this.props로 접근

import { Component } from "react";

class MainHeader extends Component {
    render () {
        const { text, name } = this.props;
        return (
            <div>
                <h1>{text}</h1>
                <h1>{name}</h1>
            </div>
        )
    }
}

export default MainHeader;

 

🚩 배열 전달

// App.js
import CustomLists from './components/CustomLists';
	const nameArr = ['뽀로로', '루피', '크롱'];
		<CustomLists arr={nameArr} />
// src/components/CustomLists.js
export default function CustomLists(props) {
    return (
        <ul>
            {props.arr.map((el) => {
                return <li>{el}</li>
            })}
        </ul>
    )
}

 

🚩 객체 전달

// App.js
import CustomObj from './components/CustomObj';

	const pororo = {
        name: "뽀로로",
        age: "5",
        nickName: "사고뭉치"
 	}
    
    	<CustomObj obj={pororo} />
// src/components/CustomObj.js
export default function CustomObj(props) {
	const { name, age, nickName } = props.obj;
    return (
        <div>
            <h1>이름 : {name}</h1>
            <h1>나이 : {age}</h1>
            <h1>별명 : {nickName}</h1>
        </div>
    )
}

 

실습: props와 state 활용하기

  • 프로필 변경하기 버튼을 클릭하면 props로 전달된 objArr의 값이 순서대로 변하는 ChangeObj.js 컴포넌트 만들기
// App.js
import ChangeObj from './components/ChangeObj';
	
    const pororoObj = [
    {
      name: "뽀로로",
      age: "5",
      nickName: "사고뭉치"
    },
    {
      name: "루피",
      age: "4",
      nickName: "루피"
    },
    {
      name: "크롱",
      age: "4",
      nickName: "크롱"
    }
  ];
  
  	<ChangeObj objArr={pororoObj} />
// src/components/ChangeObj.js
import React, { useState } from 'react';

export default function ChangeObj(props) {
    const [index, changeIndex] = useState(0);
    let obj = props.objArr[index];
    const onChange = () => {
        changeIndex(index + 1);
        if(index === props.objArr.length - 1) changeIndex(0);
    };

    return (
        <div>
            <h1>name: {obj.name}</h1>
            <h1>age: {obj.age}</h1>
            <h1>nickName: {obj.nickName}</h1>
            <button onClick={onChange}>프로필 변경하기</button>
        </div>
    )
}

 

🔎 컴포넌트 꾸미기

🚩 인라인 스타일을 바로 적용

  • JSX 문법을 통해 style 속성 값을 객체로 선언하여 직접 삽입
// src/components/TestCss.js
const divStyle = { backgroundColor: "orange" };
const headingStyle = { color: "blue" };
const spanStyle = { backgroundColor: "pink", fontWeight: "700" };

export default function TestCss() {
    return (
        <div className="component-root" style={divStyle}>
            <h1 style={headingStyle}>인라인 방법으로 CSS 적용하기</h1>
            <span style={spanStyle}>스팬 태그입니다</span>
        </div>
    )
}

 

🚩 기본 CSS로 꾸미기

  • src/style/같은 이름의 css 파일
// src/components/TestCss.js
import '../style/TestCss.css';

export default function TestCss() {
    return (
        <div className="component-root">
            <h1>h1 태그입니다</h1>
            <span>스팬 태그입니다</span>
        </div>
    )
}
div.component-root {
    background-color: lightblue;
}

div.component-root h1 {
    color: green;
}

div.component-root span {
    background-color: lightcoral;
    font-weight: 700;
}

 

🚩 Sass 사용하기

  • 설치: [터미널] npm i node-sass
// src/style/TestCss.scss
div.component-root {
    background-color: lightblue;

    h1 {
        color: green;
    }

    span {
        background-color: lightpink;
        font-weight: 700;
    }
}

 

🚩 styled components

  • 컴포넌트는 상대적으로 작은 규모이기 때문에 기존처럼 css 파일을 분리해서 운영할 필요가 적음
  • 자기만의 이름으로 태그를 구성한 뒤, 각각의 태그를 변수에 할당하고 실제 태그명을 styled를 이용하여 지정
  • 설치: [터미널] npm i styled-components
import styled from "styled-components";

const MyDiv = styled.div`
    background-color: orange;
`;

const MyHeading = styled.h1`
    color: blue;
`;

const MySpan = styled.span`
    background-color: pink;
    font-weight: 700;
`;

export default function TestStyled() {
    return (
        <MyDiv>
            <MyHeading>h1 태그입니다</MyHeading>
            <MySpan>span 태그입니다</MySpan>
        </MyDiv>
    )
}

 

🔎 조건부 렌더링

  • 상황에 따라 컴포넌트를 보여줄지 말지를 결정해야 할 때 사용
// src/components/ConditionalRender.js
export default function ConditionalRender() {
    return (
        <h1>I'm visible</h1>
    )
}
// App.js
import ConditionalRender from './components/ConditionalRender';

	const [condition, setCondition] = useState("visible");
        const onChange = () => {
            condition === "visible" ? setCondition("invisible") : setCondition("visible");
        }

    	const ConditionRender = condition === "invisible" && <ConditionalRender />;
    
            {ConditionRender}
            <button onClick={onChange}>{condition}</button>

 

🔎 useRef

  • 참조하고자 하는 태그에 ref 속성을 주고 해당 태그의 변화를 감지할 수 있음(리렌더링 x)
  • 컴포넌트에 존재하는 인풋과 포커스를 관리하기 위해 사용
// /src/components/TestRef.js
import { useState, useRef } from "react";

export default function TestRef() {
    const [text, setText] = useState("안녕하세요");

    const inputValue = useRef();
    
    const onChangeText = () => {
        console.log(inputValue);
        setText(inputValue.current.value);
    }

    return (
        <div>
            <h1>{text}</h1>
            <input ref={inputValue} onChange={() => { onChangeText() }}></input>
        </div>
    )
}

 

🚩 useRef focus

  • useRef로 각각 인풋의 속성 값을 변수에 담고 해당 변수를 통해 input 태그에 포커스 부여하기
  • 해당 값에 대한 접근은 current 객체를 통해 함
// src/components/ChangeFocus.js
import { useRef } from "react";

export default function ChangeFocus() {
    const input1 = useRef();
    const input2 = useRef();

    const changeFocusOne = () => {
        input1.current.focus();
    }

    const changeFocusTwo = () => {
        input2.current.focus();
    }

    return (
        <div>
            <input ref={input1}></input>
            <input ref={input2}></input>
            <br></br>
            <button onClick={changeFocusOne}>1</button>
            <button onClick={changeFocusTwo}>2</button>
        </div>
    )
}