리액트(React)

리액트에서 함수 component를 사용하여 state다루기(div추가/div삭제) 훅(Hook)

changy0ng 2022. 7. 25. 16:27

일단은 함수형 컴포넌트에서 관리하는거니까 -> 새 컴포넌트 만들기

Nemo.js 폴더를 src밑에 만들고 

 

//함수형 컴포넌트 기본양식

import React from "react";
//화살표
const Nemo = (props) => {
    return null;
}

export default Nemo

그리고 App.js에서 

import React from "react";
//이부분이 import해오는 부분
import Nemo from "./Nemo.js";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      //이 숫자를 가지고 배열을 만들고 배열을 만든 후 배열만큼 map돌려주면됨
      count: 3,
    };
  }

  //이 state를 콘솔에서 조금 확인하고 싶기때문에
  componentDidMount() {}

  //네모하나 추가
  addNemo = () => {
    //setState()은 위에 있는 this.state을 바꿔주는것임, 딕셔너리 형태이니 {}를 안에넣기
    this.setState({ count: this.state.count + 1 });
  };

  removeNemo = () => {
    if (this.state.count > 0) {
      this.setState({ count: this.state.count - 1 });
    } else {
      window.alert("네모가없어요!");
    }
  };

  render() {
    //배열만들기(배열의 길이로 가져오면 되는데, length가 key가 되고 숫자가 값, 그리고 새로 만든 이 배열에 요소 하나하나 인덱스 값을 넣어줌)
    const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);

    console.log(this.state);
    return (
      <div className="App">
         //이부분이 Nemo 추가해준 부분
        <Nemo /> 
        {nemo_count.map((n, i) => {
          return (
            <div
              key={i}
              style={{
                width: "150px",
                height: "150px",
                backgroundColor: "#ddd",
                margin: "10px",
              }}
            >
              nemo
            </div>
          );
        })}

        <div>
          <button onClick={this.addNemo}>하나 추가</button>
          <button onClick={this.removeNemo}>하나 빼기</button>
        </div>
      </div>
    );
  }
}
export default App;

밑에 저 div 양식은 이제 다 필요없어짐 저건 다 nemo.js에서 함수형컴포넌트로 만들어줄거기 때문

 

이제 Nemo.js에

 

//nemo.js
import React from "react";

const Nemo = (props) => {
    const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
  return (
    {nemo_count.map((n, i) => {
        return (
          <div
            key={i}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        <button onClick={this.addNemo}>하나 추가</button>
        <button onClick={this.removeNemo}>하나 빼기</button>
      </div>
  );
};

export default Nemo;

이렇게 뷰 부분을 붙여주면 에러가 생기는데 parsing error가 생김, 그리고 return은 반드시 1개

return 안에 들어올수 있는 요소는 리액트 요소거나 string일때만 들어올 수 있다
이럴때는 감싸는 요소를 하나 만들어주면 된다

이러면 감싸는 빈 태그 하나만 리턴을 해주게 된다

 

//nemo.js
import React from "react";

const Nemo = (props) => {
  const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
  return (
    <>
      {nemo_count.map((n, i) => {
        return (
          <div
            key={i}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        <button onClick={this.addNemo}>하나 추가</button>
        <button onClick={this.removeNemo}>하나 빼기</button>
      </div>
    </>
  );
};

export default Nemo;

근데 error가 많이 생기는데 우선 Type Error:Cannot Read property 'state' of undefined가 뜨게 되는데 
일단 이 nemo 컴포넌트는 state라는 것도 없고 count라는 것도 없음

그래서 일단

//nemo.js
import React from "react";

const Nemo = (props) => {
  const nemo_count = Array.from({ length: 3 }, (v, i) => i);
  return (
    <>
      {nemo_count.map((n, i) => {
        return (
          <div
            key={i}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        <button>하나 추가</button>
        <button>하나 빼기</button>
      </div>
    </>
  );
};

export default Nemo;

이렇게 값들을 다 빼주고 밑에 button들 onclick속성도 다 빼줌

이제 뷰는 다 작성했으니

그리고 이제 length는 3으로 넣어줬지만 이제 state를 넣어줘야 저게 addNemo같은 것을 실행시켜줄수있음
this.state로 사용할수없었는데 useState이라는 훅을 사용하면 쉽게 할수있음

우리는 count라는 state만들기

//nemo.js

import React from "react";

const Nemo = (props) => {
  //React.useState이라는 훅을 써서 state를 만드는 건데 count = state값, setCount = state를 바꾸기(count를 변경하는 함수)
  //3은 state에 들어가는 초기값
  const [count, setCount] = React.useState(3);
  console.log(count);
  const nemo_count = Array.from({ length: count }, (v, i) => i);

  return (
    <>
      {nemo_count.map((n, i) => {
        return (
          <div
            key={i}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        <button>하나 추가</button>
        <button>하나 빼기</button>
      </div>
    </>
  );
};

export default Nemo;

근데 이 Nemo는 클래스형 컴포넌트가 아니기 때문에
js 쓰는 부분에 addNemo = () => {
}
이런식으로쓰면 실패함(addNemo is not defined) 나옴

그래서 함수형에서는 선언을 해줘야함

 

import React from "react";

const Nemo = (props) => {
  //React.useState이라는 훅을 써서 state를 만드는 건데 count = state값, setCount = state를 바꾸기(count를 변경하는 함수)
  //3은 state에 들어가는 초기값
  const [count, setCount] = React.useState(3);
  console.log(count);
  const nemo_count = Array.from({ length: count }, (v, i) => i);

  const addNemo = () => {
    setCount(count + 1);
  };
  return (
    <>
      {nemo_count.map((n, i) => {
        return (
          <div
            key={i}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        <button onClick={addNemo}>하나 추가</button>
        <button>하나 빼기</button>
      </div>
    </>
  );
};

export default Nemo;

 

이렇게 하면 추가가 됨
반대로 삭제는

 

//nemo.js

import React from "react";

const Nemo = (props) => {
  //React.useState이라는 훅을 써서 state를 만드는 건데 count = state값, setCount = state를 바꾸기(count를 변경하는 함수)
  //3은 state에 들어가는 초기값
  const [count, setCount] = React.useState(3);
  console.log(count);
  const nemo_count = Array.from({ length: count }, (v, i) => i);

  const addNemo = () => {
    setCount(count + 1);
  };
  const removeNemo = () => {
    if (count > 0) {
      setCount(count - 1);
    } else {
      window.alert("네모가 없어요!");
    }
  };
  return (
    <>
      {nemo_count.map((n, i) => {
        return (
          <div
            key={i}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        <button onClick={addNemo}>하나 추가</button>
        <button onClick={removeNemo}>하나 빼기</button>
      </div>
    </>
  );
};

export default Nemo;

다시정리하면

1. useState 리액트 훅 써가지고 state를 넣어줄 값(count) 와 그 값을 바꿔줄 함수 setState을 만들어줌, 그리고 그안에는 초기값
const [count, setCount] = React.useState(3);

2. 그리고 불러올 때 쓰는 거는 class때와 똑같이이것을 써서 숫자만 불러옴
const nemo_count = Array.from({ length: count }, (v, i) => i);