리액트 기초반 2주차 - 2

43069 단어 ReactReact

22년 4월 3일(일)
[스파르타코딩클럽] 리액트 기초반 - 2주차

◎ React에서 CSS 사용하기

  • CSS 파일을 가져다 쓰려면, 아래와 같이 이용
import './style.css'
  • 부모와 같은 스타일 파일을 쓸 때는 부모 컴포넌트에만 import하면 된다. (자식 컴포넌트는 return에 들어 있는 리액트 요소를 부모 컴포넌트에 가져다 준다.)

◎ styled-components

  • styled-components 설치
yarn add styled-components
  • styled-components : 컴포넌트 스타일링 기법 중 편한 방식
    • 모든 요소에 className을 지을 필요가 없다.
    • Component에 스타일을 적기 때문에, 간단하고 직관적입니다!
    • SCSS 문법 사용 가능
  • styled-components plugin 설치
    -> VSCode에서 쉽게 작성하기 위해 확장 탭에서 vscode-styled-components 설치를 추천
  • 예시
import React from 'react';
import BucketList from './BucketList';
import "./style.css";
import styled from "styled-components";

// 클래스형 컴포넌트는 이렇게 생겼습니다!
class App extends React.Component {

    constructor(props) {
        super(props);
        // App 컴포넌트의 state를 정의해줍니다.
        this.state = {
            list: ['영화관 가기', '매일 책읽기', '수영 배우기']
        };

        this.text = React.createRef();
    }

    addList = () => {
        console.log(this.text.current.value);
        this.setState({list:[...this.state.list, this.text.current.value]})
        console.log(this.state.list);
    }

    // 랜더 함수 안에 리액트 엘리먼트를 넣어줍니다!
    render() {
        return (
            <div className="App">
                <BucketListDiv>
                    <h1>내 버킷리스트</h1>
                    <hr/>
                    <BucketList list={this.state.list}/>
                </BucketListDiv>
                <InputDiv>
                    <input ref={this.text}/>
                    <button onClick={this.addList}>추가하기</button>
                </InputDiv>
            </div>
        );
    }
}

const Maindiv = styled.div`
    width: 50vw;
    max-height: 150px;
    background-color: ${(props) => (props.bg_color ? "red":"#ddd")};
    p {
        color: blue;
    }

    &:hover{
        background-color: #444;
    }
`

const BucketListDiv = styled.div`
    background-color: #fff;

    width: 50vw;
    max-width: 350px;
    height: 80vh;

    margin: auto;
    padding: 16px;

    border: 1px solid #ddd;
    border-radius: 5px;

    h1 {
        color: slateblue;
        text-align: center;
    }

    hr {
        margin: 16px 0px;
    }

    .listItme {
        padding: 16px;
        margin: 16px 8px;
        background-color: aliceblue;
    }
`
const InputDiv = styled.div`
    background-color: #fff;

    width: 50vw;
    max-width: 350px;
    height: 10vh;

    margin: auto;
    margin-top: 10px;
    padding: 16px;

    border: 1px solid #ddd;
    border-radius: 5px;

    button {
        margin: 5px;
    }

    input {
        font-size: 15px;
    }
`

export default App;

◎ Ref : React에서 DOM요소 가져오기

  • Class형 Component 예시
import React from "react";
import BucketList from "./BucketList";


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
    };
    // ref는 이렇게 선언합
    this.text = React.createRef();
  }

  componentDidMount(){
	// rendering 다 된 후에 바로 inputbox에서 바로 가져오므로 빈 값이 넘어옴
    console.log(this.text); // ""
	console.log(this.text.current); // ""
  }


  render() {
    
    return (
      <div className="App">
        <Container>
          <Title>내 버킷리스트</Title>
          <Line />
          <BucketList list={this.state.list} />
        </Container>

        <div>
          // ref 요소 지정
          <input type="text" ref={this.text}/>
        </div>
      </div>
    );
  }
}

export default App;
  • 함수형 Component 예시
import React from "react";

const BucketList = ({ list }) => {
  const my_lists = list;
  const my_wrap = React.useRef(null); 

  console.log(my_wrap); // 콘솔로 확인해봐요!

  // 1초 뒤에 실행
  window.setTimeout(() => { 
    console.log(my_wrap); // <div> 안에 있는 내용들을 나태내줌
  }, 1000);
  
  return (
    <div ref={my_wrap}>
      {my_lists.map((list, index) => {
        return <ItemStyle key={index}>{list}</ItemStyle>;
      })}
    </div>
  );
};

export default BucketList;

◎ State 관리

  • 단방향 데이터 관리
    -> 데이터는 위에서 아래로, 부모에서 자식으로 넘겨줘야 한다.
    -> 서로가 서로 props를 줄 때,
    A state 업데이트 -> B 리랜더링 -> A 리랜더링 -> B 리랜더링 ...

  • Class형 Component 예시
    -> this.setState()를 통해 state 관리 // Java class의 Setter개념

import React from "react";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 3, // 숫자넣기!
    };
  }

  addNemo = () => {
    // this.setState로 count를 하나 더해줍니다!
    this.setState({ count: this.state.count + 1 });
  };

  removeNemo = () => {
    if (this.state.count > 0) {
      // this.setState로 count를 하나 빼줍니다!
      this.setState({ count: this.state.count - 1 });
    }else{
      window.alert('네모가 없어요!');
    }
  };

  render() {
    // 배열을 만듭니다.
    // Array.from()은 배열을 만들고 초기화까지 해주는 내장 함수입니다.
    // Array.from()의 첫번째 파라미터로 {length: 원하는 길이} 객체를,
    // 두번째 파라미터로 원하는 값을 반환하는 콜백함수를 넘겨주면 끝!
    // array의 내장함수 대부분은 콜백 함수에서 (현재값, index넘버)를 인자로 씁니다.
    const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);

    // 콘솔로 만들어진 배열을 확인해봅니다. 숫자가 0부터 순서대로 잘 들어갔나요?
    console.log(nemo_count);

    return (
      <div className="App">
      /* return 안에서 map(반복문) 사용시, 고유한 key값을 강제적으로 부여할 것 */
        {nemo_count.map((num, idx) => {
          return (
            <div
              key={idx}
              style={{
                width: "150px",
                height: "150px",
                backgroundColor: "#ddd",
                margin: "10px",
              }}
            >
              nemo
            </div>
          );
        })}

        <div>
          /*이 클래스 안의 함수를 불러오기 때문에 this.addNemo로 표기해요. */
          <button onClick={this.addNemo}>하나 추가</button>
          <button onClick={this.removeNemo}>하나 빼기</button>
        </div>
      </div>
    );
  }
}

export default App;
  • 함수형 Component 예시
    -> const [count, setCount] = React.useState(); 이용
import React from "react";

const Nemo = (props) => {
  // count에는 state 값이, setCount는 count라는 state 값을 수정하는 함수가 될거예요.
  // useState(초기값): () 안에 초기값을 넣어줍니다.
  const [count, setCount] = React.useState(3);

  const addNemo = () => {
    // setCount를 통해 count에 저장된 값을 + 1 해줍니다.
    setCount(count + 1);
  };

  const removeNemo = () => {
    // setCount를 통해 count에 저장된 값을 - 1 해줍니다.
    setCount(count > 0 ? count - 1 : 0);
  };

  const nemo_count = Array.from({ length: count }, (v, i) => i);
  // 반환할 리액트 요소가 없을 때는 null을 넘겨주세요!
  return (
    <div className="App">
      {nemo_count.map((num, idx) => {
        return (
          <div
            key={idx}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        {/* 함수를 호출합니다. */}
        <button onClick={addNemo}>하나 추가</button>
        <button onClick={removeNemo}>하나 빼기</button>
      </div>
    </div>
  );
};

export default Nemo;

좋은 웹페이지 즐겨찾기