리액트

ssongyi·2022년 5월 25일
0

리액트

목록 보기
1/3

————————————————————————————————————————————————————————————————————————————————————————————————
1. 세팅하기
————————————————————————————————————————————————————————————————————————————————————————————————
<생초기 세팅>
-NvM 설치확인
nvm --version
-NvM으로 노드 설치
nvm install [설치할 버전]
-설치완료 후 확인
node -v # 노드 버전 확인 명렁어
-사용할 버전으로 맞추기 (보통 LTS버전 씀)
nvm use [사용할 노드 버전]
-npm으로 yarn 설치 (npm은 노드 설치시 자동으로 설치됨.)(yarn add로 원하는 패키지 설치)
npm install -g yarn
-CRA(create-react-app)으로 시작하는 리액트 설치

옵션 global은 전역에 이 패키지를 깔겠다는 뜻입니다.

yarn add global create-react-app

<프로젝트 시작할 때>
-리액트 프로젝트 생성
yarn create react-app [프로젝트 폴더이름]
-Styled-components 설치
yarn add styled-components
import styled from "styled-components"; (추가 후 사용)

-React-router-dom 설치
yarn add react-router-dom@5.2.1 (강의랑 버전 맞추기 위해 @5.2.1버전으로 설치함, @떼면 최신버전)

-프로젝트 실행(폴더 안에서) (실행종료 control+c)
yarn start

**두번씩 콘솔찍힐때
index.js에서 React.StrictMode 삭제
———————————————————————————————————————————————————————

  1. 만들 페이지 라우팅 해주기
    ———————————————————————————————————————————————————————
    <1. index.js에 App.js 로 감싸주기>

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
//App.js 받아오고
import { BrowserRouter } from "react-router-dom";
// BrowserRouter 사용 위해 임포트!

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(

{/ BrowserRouter로 App.js 감싸주기 /}


);
———————————————————————————————————————————————————————
<2. App.js에서 만들 페이지들 하기 + 모든페이지 공통 props만들어주기>

import React from "react";
import { Route } from "react-router-dom";
// Route 사용 위해 임포트!
import Main from "./Main";
import Detail from "./Detail";
// 만든 페이지들 가져오기!

function App() {
const days = ["월", "화", "수", "목", "금", "토", "일"];
//모든 페이지에서 사용될 값들을 만들어서, 아래에서 props로 보내줌!

return (

<div className="App">
  <Container>
    {/* 담을 container 만들어서 컴포넌트들(페이지들) 담기 */}
    <Route path="/" exact>
      {/* Route로 감싸는데 path="" 작성,(메인은 주로 /), exact로 완전히 같을 때만 보여줘! (exact 없을경우 포함하면 다 보여줘) */}
      <Main days={days} />
      {/* 컴포넌트(페이지) 넣어주기, 넣어줄 때 props 넘겨줄 수 있음. props이름은 내마음대로 작성! */}
    </Route>
    <Route path="/detail/:id" exact>
      {/* path에 /:id로 파라미터 전송가능! 
      파라미터 보내는 페이지에서는 <Link to={`/detail/${id}`}> 이런식으로 넣어줌!
      파라미터는 데이터를 받을 페이지에서 useParams를 리액트-라우터-돔으로 임포트해서 사용! */}
      <Detail days={days} />
    </Route>
  </Container>
</div>

);
}
export default App;
// index.js에서 받아야 하므로 export default 필수!

*컴포넌트를 다 함수로 만들어서 const 000 = () => {return()} -> container에 컴포넌트를 담은다음(컨테이너도 함수로,컴포넌트 첫글자 대문자로!)
-> App에 넣어줌
————————————————————————————————————————————————————————————————————————————————————————————————
<3. 컴포넌트(페이지) 만들기>
import React from "react";
import styled from "styled-components";

const Page= (props) => {
return

메인 화면입니다!
;
};

export default Page;
———————————————————————————————————————————————————————
<잘못된 주소 처리하기>
exact로 중복 주소를 처리하는 방법은 이미 배웠습니다! 이번엔 우리가 미리 정하지 않은 주소로 들어온 경우를 다뤄볼게요.

(1) 일단 NotFound.js 파일을 만들고 빈 컴포넌트를 만들어주세요.
import React from "react";

const NotFound = (props) => {
return

주소가 올바르지 않아요!

;
};

export default NotFound;

(2)App.js에서 불러옵니다.

(3)Switch를 추가해주고,
import { Route, Switch } from "react-router-dom";

(4)NotFound컴포넌트를 Route에 주소 없이 연결하면 끝!

<Route
path="/"
exact
render={(props) => }
/>




(추가) 뒤로가기버튼 - NotFound.js에 추가
import React from "react";
import { useHistory } from "react-router-dom";

const NotFound = (props) => {
const history = useHistory();
return (
<>

  <h1>주소가 올바르지 않아요!</h1>
  <button
    onClick={() => {
      history.push("/");
    }}
  >
    뒤로가기
  </button>
</>

);
};
———————————————————————————————————————————————————————
3. State 관리
———————————————————————————————————————————————————————
useState 훅을 통해서 관리 가능!

const [data, data를 변경시킬함수] = React.useState(초기값(0 or "" or [])); -> useState 이용해서 계속 변화하는 평균값 넣어줌
Ex) const [avg, setAvg] = React.useState(avgNum.toFixed(1));
// avg로 data지정, 변경시킬 함수는 주로 data 앞에 set을 붙임 setAvg/ React.useState로 훅 사용/초기값은 지금 화면의 값들의 평균값인 avgNum넣고 .toFixed(1)로 소수점 아래 1자리까지 출력!
Ex) const reset = () => setAvg(0.0);
//버튼 누르면 실행될 reset함수/ setAvg(0.0)으로 바꿔줌! -> 이런 식으로 함수로 불러와서 값 변경해줌!
————————————————————————————————————————————————————————————————————————————————————————————————
1.
function App() {
const [counter, modifier] = React.useState(0);
// [date, data를 변경시킬 함수]

const Title = () => {
return

Total clicks: {counter}

; //data를 넣어줌
};

다음 data를 변경시킬 함수를 만들어줌

  1. function App() {
    const [counter, setCounter] = React.useState(0); //주로 modifier라 안하고 set을 붙여줌 data에
    // [date, data를 변경시킬 함수]
    const onClick = () => {
    //setCounter(counter + 1); //data에 변경값주고
    setCounter((current)=>current + 1);
    };

    const Title = () => {
    return

    Total clicks: {counter}

    ;
    };

이러면 자동 리렌더링까지 해줌!

<state값 변경해주기>

  • setcounter에 그냥 숫자나 문자열 넣기
  • setCounter((current)=>current + 1); 로 넣기 현재 값을 바탕으로 더해줌, 더 안전한 방법!!

———————————————————————————————————————————————————————
4. 페이지 이동
———————————————————————————————————————————————————————

import { Link } from "react-router-dom"; // Link사용 위해 임포트 {/* 링크를 이용하여 세모 눌렀을 때 id값 파라미터로 주면서 /detail로 이동 */} //이런식으로 링크로 감싸줌!

<history 이용하기>
import { useHistory } from "react-router-dom";
// useHistory 사용위해 임포트

컴포넌트 안에
const history = useHistory();
//.history로 바로 사용가능하게
사용할 곳에 불러와서 사용
<button onClick={()=>history.push(“/”)}>

———————————————————————————————————————————————————————
5. Props 받기
———————————————————————————————————————————————————————
페이지 시작할 때 받아옴
const Main = (props) => {
const days_list = props.days;
// 받아온 데이터를 알맞게 이름지어서 사용!
return null;};
———————————————————————————————————————————————————————
function App() {
const MainBtn = (props) => { //2. props를 넣어 props.이름해서 꺼내 쓰거나
return {props.text}; //props대신 {이름}을 넣어 바로사용가능, {이름1,이름2}여러개 사용가능
};

return (

<div className="App">
  <MainBtn text="Save Changes" big={true} />		//1. props를 만든다. 원하는 이름으로 몇개를 만들든 props에 담긴다.
  <MainBtn text="Continue" big={false} />
</div>

);
}
const Btn = styled.button background-color: tomato; color: white; padding: 10px 20px; border: 0; border-radius: 10px;;

———————————————————————————————————————————————————————
6. .map()으로 나열하기
———————————————————————————————————————————————————————
{/ 나열해주기 리스트 /}

  <ul>
    {toDos.map((item, index) => (
      //2. 그래서 index를 추가해줌, item 주면서 번호붙여서줌!
      <li key={index}>{item}</li>
      // 1. item에 key를 넣어줘야함!
    ))}
  </ul>

———————————————————————————————————————————————————————

내 일주일은? {days_list.map((list, id) => { //.map((item, index)=>{
  • {item}
  • }) //map()함수를 통해 days_list의 내용물을 아래 모양으로 나열해줌(생성)! //item에 key 넣어줘야함! return ( {list} <> {/* 리턴 2개면 안되서 빈배열 넣어주기! */} {circle.map((v, i) => { //동그라미 랜덤한 수 만큼 보라색으로 색칠해주기 위한 .map() const number = num[id]; // 위에서 정의한 num(랜덤수)에 [id]로 순서 맞춰서(월화수..) number로 정의해줌! return ( 즉, number만큼 색칠하겠다는 뜻! }} > ); })} {/* 링크를 이용하여 세모 눌렀을 때 id값 파라미터로 주면서 /detail로 이동 */} ); })}

    ———————————————————————————————————————————————————————
    7. 파라미터 값 보내고 받기
    ———————————————————————————————————————————————————————
    <1. App.js에서 미리 어떤이름으로 보낼지 정해줌>

    {/* path에 /:id로 파라미터 전송가능!

    <2. 보내는 페이지에서 >

    	<Link to={`/detail/${id}`}>
              {/* 링크를 이용하여 세모 눌렀을 때 id값 파라미터로 주면서 /detail로 이동 */}
            	  <Triangle></Triangle>
           	 </Link>

    <3. 받는페이지에서>
    import { Link, useParams } from "react-router-dom";
    //파라미터는 데이터를 받을 페이지에서 useParams를 리액트-라우터-돔으로 임포트해서 사용! */}

    const Detail = (props) => {
      const { id } = useParams();

    // useParams 훅으로 파라미터 값인 id값 받아옴!

     이런식으로 사용
     <h3>
        <Day>{props.days[id]}요일</Day> 평점 남기기
        {/* 받아온 파라미터로 몇번째인지 알 수 있고, 그걸 통해 props에 .days에 무슨 요일인지 알 수 있음! */}
      </h3>

    ———————————————————————————————————————————————————————
    8. Input과 state
    ———————————————————————————————————————————————————————
    function App() {
    const [minutes, setMinutes] = React.useState();
    const onChange = (event) => { //3.event추가 -> 이벤트 발생시
    setMinutes(event.target.value); // 4. 입력된 값으로 변화
    };
    const Container = () => {
    return (

      <div>
        <Title />
        <label htmlFor="minutes">Minutes</label>
        <input
          value={minutes}		//1.값을 minutes로
          id="minutes"
          type="number"
          placeholder="Minutes"
          onChange={onChange} //2. onChange를 통해 변화를 감지해서
        ></input>
      </div>
    );

    };
    return (

    <div className="App">
      <Container />
    </div>

    );
    }
    ———————————————————————————————————————————————————————

    1. 한번만 실행하고 싶은 코드
      ———————————————————————————————————————————————————————
      useEffect
    • 두 개의 argument를 가지는 함수

    • 첫 번째 argument는 우리가 딱 한번만 실행하고 싶은 코드

    • 두 번째는 [] 배열을 넣어줌
      -> useEffect가 컴포넌트의 첫 번째 렌더 시점에 iRunOnlyOnce 함수 호출
      그리고 상태를 변화시키면 iRunOnlyOnce는 호출되지 않음
      즉, 한번만 렌더링 됨
      단순화 하여 useEffect(() => {
      console.log("CALL THE API")
      },[]); 써도 됨
      -> []를 지켜봐라인데 지켜볼게 없어서 한번만 실행됨.
      만약

      useEffect(() => {
      if (keyword !== "" && keyword.length > 5) { // 조건도 추가해줄수 있다. 만약 keyword가 빈칸이아니고 길이가 5이상 일때
      console.log("SEARCH FOR", keyword);
      }
      }, [keyword]);

    -> keyword가 변화할때만 실행됨.
    ———————————————————————————————————————————————————————
    10. EventListner
    ———————————————————————————————————————————————————————
    이벤트 리스너는 사용자가 어떤 행동(=이벤트)을 하는 지 아닌 지 지켜보다가 알려주는 것입니다.
    대표적으로는 마우스 클릭, 터치, 마우스 오버, 키보드 누름 등이 자주 쓰여요!
    getElementby~~로 요소 잡아와서 addEventListener달아주자! ref로 데리고 와서 addEventListener 달아줌!

    addEventListener를 사용하려면 dom요소까지 완성이 되어 있어야함. 따라서 마운트가 끝나야함. 고로 DidMount에 넣음

    만든 이벤트리스너는 컴포넌트가 사라질 때 함께 사라져야함! WillUnmonut에서 제거해주자

    <클래스형 컴포넌트에서 Event Listener>

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

    this.state = {};
    this.circle = React.createRef(null); //1. Ref로 요소 가져옴

    }
    //2. 이벤트 함수 작성
    hoverEvent = (e) => {
    //이벤트를 파라미터로 받아온다
    console.log(e.target); //이벤트가 발생한 요소를 가져옴
    console.log(this.circle.current);
    this.circle.current.style.background = "yellow"; //4. 바꿀 변경사항 작성
    };

    componentDidMount() {
    console.log(this.circle);
    //3. addEventListener를 사용하려면 dom요소까지 완성이 되어 있어야함. 따라서 마운트가 끝나야함. 고로 DidMount에 넣음
    // this.circle.current.addEventListener(어떤이벤트, 어떤행동할게)
    this.circle.current.addEventListener("mouseover", this.hoverEvent);
    }

    //5. 컴포넌트 사라질때 이벤트리스너도 같이 지워져야함!
    componentWillUnmount() {
    this.circle.current.removeEventListener("moserover", this.hoverEvent);
    }

    render() {
    return (

      <div style={{ width: "100vw", height: "100vh", textAlign: "center" }}>
        <Text />
        <div
          style={{
            margin: "auto",
            width: "250px",
            height: "250px",
            background: "green",
            borderRadius: "250px",
          }}
          ref={this.circle}
        ></div>
      </div>
    );

    }
    }

    <함수형 컴포넌트에서 Event Listener>

    const Text = (props) => {
    const text = React.useRef(null);

    const hoverEvent = () => {
    //2. 이벤트 함수생성
    text.current.style.background = "yellow";
    };
    //리액트 훅 중에 하나! DidMount, DidUpdate,WillunMount 세개를 합쳐준 것
    //컴포넌트가 렌더링 되면 화살표 함수를 실행 ()=>{} /첫번째 실행은 무조건 실행됨. 두번째 실행부터는 뒤에 [Dependency Array]의 요소를 확인해서 바뀐게 있다면 실행
    //1. useEffect훅 만들어주기
    React.useEffect(() => {
    text.current.addEventListener("mouseover", hoverEvent); //3.이벤트리스너 넣기
    //4. useEffect 안에서 리턴이 WillunMount 역할
    return () => {
    text.current.removeEventListener("mouseover", hoverEvent);
    };
    }, []);
    return

    텍스트입니다!

    ;
    };
    ———————————————————————————————————————————————————————
    Last. 마지막으로 styled 입혀주기!
    ———————————————————————————————————————————————————————
    가장 아래 작성

    const Wrap = styled.div`
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow-x: hidden;
    overflow-y: auto;

    .button {
    으로 내부에 것도 가능!
    };
    `;

    ———————————————————————————————————————————————————————
    클래스형 컴포넌트
    ———————————————————————————————————————————————————————

    클래스형 컴포넌트 생성 순서
    1. import React from “react”;

    1. class App extends React.Component {}

    2. class App extends React.Component {
      render (){
      return ()
      }
      }

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

      this.state = {};

    }
    render (){
    return ()
    }
    }

    ——————————————————
    21) 클래스형 컴포넌트에서 state 관리 - setState()

    import React from "react";

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

    this.state = {					//네모 초기 개수 설정
      count: 3,
    };

    }
    componentDidMount() {}

    addNemo = () => {
    this.setState({ count: this.state.count + 1 }); // setState()로 컴포넌트의 state값 업데이트(같은 형식으로 딕셔너리형이여서 똑같이 함)
    };

    removeNemo = () => {
    if (this.state.count > 0) {
    this.setState({ count: this.state.count - 1 });
    } else {
    window.alert("네모가 없어요!");
    }
    }; //렌더 위에서 네모추가 함수 작성

    render() {
    const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);

    return (
      <div className="App">
        {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>			// onClick={} 해서 this.함수 넣어주기,but ()붙이면 즉시실행됨.
          <button onClick={this.removeNemo}>하나 빼기</button>
        </div>
      </div>
    );

    }
    }

    export default App;

    0개의 댓글