본문 바로가기

sparta/REACT

[REACT]스탠다드 복습4회차_메모 (중요⭐, 매일보기)

화살표함수

중괄호가 있으면 return넣어라.

가급적이면 바로 return할 수 있으면 중괄호 넣지마라.

if문이나 표현식이 아닌 걸 써야한다면 중괄호를 열어줘라.

 

? 컴포넌트가 아니라 객체를 return하고 싶을때,

const foo =()=>{a:10}
foo()
// undefined

* void함수: return키워드가 없는 함수

const foo =()=>({a:10})
foo()
// {a: 10}

소괄호로 묶으면 객체.


이벤트핸들러 주의사항
<button
        onClick={(el) => {
          setCount((count) => count - el);
        }}
      ></button>

이벤트 핸들러의 매개변수, count-매개변수 xxxx

 

event는 이벤트객체, 매개변수로 전달되므로 evetn를 통해 클릭 이벤트에 대한 다양한 정보나 연산을 처리할 수 있다.

예를들면, 클릭된 요소, 마우스좌표, 키입력 값 등 여러 정보를 담고 있다.

따라서 위 코드는 이벤트 객체를 숫자연산에 사용하려고 하고 있다. 절대 안된다..

 

 

! 한번 연습해보자.

// input 상태들을 하나씩 표현했을 때
const [country, setCountry] = useState("");
const [gold, setGold] = useState(0);
const [silver, setSilver] = useState(0);
const [bronze, setBronze] = useState(0);

const handleCountryChange = (e) => {
    setCountry(e.target.value);
};

const handleGoldChange = (e) => {
    setGold(+e.target.value);
};

const handleSilverChange = (e) => {
    setSilver(+e.target.value);
};

const handleBronzeChange = (e) => {
    setBronze(+e.target.value);
};

위코드는 아래 코드로 바꿔 쓸 수 있다.

 

// input 상태들을 객체로 한번에 표현했을 때
const [countryInputData, setCounryInputData] = useState({
    country: "",
    gold: 0,
    silver: 0,
    bronze: 0,
});

const handleInputChange = (e) => {
	const { name, value } = e.target;
	setCountryInputDate({
		...countryInputData,
		[name]: name === "country" ? value : +value});
}

훨씬 깔끔하다.

계산된 속성값

위 코드에 키값에 대활호가 있는 이유, 키값은 기본적으로 문자열이다.

프로퍼티의 키값은 문자열이다.

const num='aaa'
const obj2={[num]:10}
obj2
{aaa: 10}

키를 변수화하고 싶을 때, 대괄호를 넣어라.

 

 


 

 

 

본과정

 

 

 

 

1. useState

 

import React, { useState } from "react";
  const [count, setCount] = useState(0);
const handleClick = () => {
    setCount(count + 1); // 상태변경함수는 비동기 함수!!
    console.log("1st count:", count); // TODO: 증가 버튼 클릭 시 여기 무슨 로그가 나올까요?

    setCount(count + 1);
    console.log("2nd count:", count); // TODO: 증가 버튼 클릭 시 여기 무슨 로그가 나올까요?
  };
 <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>증가</button>
    </div>

 

 

? 위코드를 보고 버튼을 누를때 어떻게 출력되는가?

 

내가 생각한 답

1st count:1
2nd count:1

 

정답

1st count:0
2nd count:0

비동기함수의 특징은 동기함수를 먼저 실행시켜놓고 마지막에 실행된다.

 

 

 

 

1. batching : 여러 작업을 한 번에 묶어서 처리하는 기법

최대한 적은 회수의 렌더링을 할 수 있게 만들어준다.

 

 

 

 

 

 

 

 

따라서 setCount가 두개지만 리렌더링은 한꺼번에 처리하기 때문에 한번만한다. =>배칭 (기술면접 용어)

즉, setState는 비동기함수다.

 

 

 

 

 

 


함수형 업데이트 :setState (업데이트함수)⭐⭐⭐

상태변경 안에 들어오는 인자에 들어오는 함수를 updater라고 부른다.

 

? 언제 쓰면 좋은가

이전(최신)상태에 의존해서 새로운 상태로 변경할 경우

setCountries(prevCountries ⇒ […prevCountries, newCountry])

기존에 있던 상태( …prevCountries )에 새로운 국가정보(newCountry)를 넣는 식으로 권장한다.

상태(state)를 업데이트할 때 사용되는 패턴인데 setCountries라는 상태변경 함수를 호출하여 prevCountries 배열에 newCountry를 추가한다는 거다.

prevCountries는 현재 countries 상태의 이전 값(즉, 현재 배열)을 나타낸다.

[...prevCountries, newCountry]는 이전 배열을 펼친(spread) 후, newCountry라는 새로운 요소를 배열의 끝에 추가한 새로운 배열을 만든다. 그래서 setCountries 함수는 새로운 배열로 countries 상태를 업데이트된다.

 

 

내가 짠 코드는 복잡하긴 하다.

const MedalForm = ({ setCountries }) => {
  const [countryName, setCountryName] = useState("");
  const [goldMedals, setGoldMedals] = useState(0);
  const [silverMedals, setSilverMedals] = useState(0);
  const [bronzeMedals, setBronzeMedals] = useState(0);
  const handleAdd = (e) => {
    // ...생략
    
    // prev부터 함수.
    setCountries((prevCountries) => [
      ...prevCountries,
      {
        id: Date.now(),
        name: countryName,
        gold: goldMedals,
        silver: silverMedals,
        bronze: bronzeMedals,
      },
    ]);
  };

 

위코드처럼 prevCountries라고 적으면 상태변경 전이라는 뜻이다.

const [count, setCount] = useState(0);
setCount(count + 1);

그러니까 위 코드를 아래 코드처럼 할 수 있다는 얘기!!!!!!!!!!!!!!!!!

 

const [count, setCount] = useState(0);
setCount(prevCount => prevCount + 1);
// setCount((이전값) => 이전값 + 1);

 

  • setCount(count + 1); : 현재의 count 값을 바로 사용하여 +1을 한다. 하지만 상태 업데이트가 비동기적으로 이루어지기 때문에 여러 번 업데이트가 필요한 경우 예상과 다르게 동작할 수 있다.
  • setCount(prevCount => prevCount + 1); : 이전 상태 값을 인자로 받아 +1을 하므로 상태가 여러 번 바뀌어도 안전하게 이전 상태를 기반으로 계산할 수 있다.

 


 

styled-components => 팀룰 꼭 정하기 👍

 

함수호출할 때 함수(); 도 있는데 함수``;도 있다..(별로안중요함)

 

 

시작할때 reset CSS 구글링해서 main.jsx 안에 넣으면 깔끔해진다.

import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
body{
  background-color:green;
}
`;

위 코드의 background-color 있는 부분에 지우고 붙여넣기 하면 된다.

 

기본스타일을 없애는 이유는 브라우저마다 다르다. 일일이 신경써가면서 코딩할 수 없기 때문에 resetCSS를 넣어야 한다는 거다.

 

! 권장하는 style=> styled reset 구글링해서 보면 패키지가 뜬다. 

import reset from "styled-reset";
const GlobalStyle = createGlobalStyle`
${reset}`;

패키지 설치해서 위 코드처럼 main.jsx에 넣어주면 간단해진다.

간단할 뿐만 아니라 유지보수성도 좋기 때문에 권장한다.

 

props를 사용한 간단한 조건부 스타일링

 

${props => (props.$primary ? 'blue' : 'gray')};
// ...생략
 background-color: ${props => (props.$primary ? 'darkblue' : 'darkgray')};

${} 는 자바스크립트 표현식을 스타일 코드에  삽입하는 방식이다. styled-components에서 컴포넌트의 스타일 속성 값을 동적으로 설정할 때 사용된다.

props는 이 스타일이 적용되는 컴포넌트에 전달된 props(속성) 객체인데 삼항연산자로 값에 따라 색을 반환한다.

<Button $primary={true}>Primary Button</Button>

따라서 버튼을 부르면 상태에 따라 색이 반환된다.

*  이때 {true}를 없애도 똑같다 디폴트가 true다.

 

헬퍼함수 => 많이 씀
import styled, { css } from 'styled-components'; // styled-components와 css 헬퍼 함수 임포트

// Button 컴포넌트 정의
const Button = styled.button`
  /* 기본 스타일 */
  padding: 10px 20px;         // 버튼의 패딩 설정
  font-size: 16px;            // 폰트 크기 설정
  border: none;               // 테두리 없음
  border-radius: 5px;         // 모서리를 둥글게 설정
  cursor: pointer;            // 마우스 커서를 포인터로 변경
  color: white;               // 글자색을 흰색으로 설정

  /* $primary prop에 따른 스타일 분기 */
  ${(props) =>
    props.$primary
      ? css` // $primary가 true일 때 적용할 스타일
          background-color: blue;         // 배경색을 파란색으로 설정
          &:hover {                       // hover 상태일 때 배경색 변경
            background-color: darkblue;    // 진한 파란색으로 변경
          }
        `
      : css` // $primary가 false일 때 적용할 스타일
          background-color: gray;         // 배경색을 회색으로 설정
          &:hover {                       // hover 상태일 때 배경색 변경
            background-color: darkgray;    // 진한 회색으로 변경
          }
        `}
`;

 

여기서 &는 해당태크를 의미한다.

 

styled component의 props는 앞에 $라는 prefix를 붙이도록. 기억기억!!!!!

 

구별하기위해 $를 붙인다. placeholder가 input에 원래 있다 하지만 input에 error사인은 개발자가 붙인 거다.

이때 사용하는 게 바로 달러.

    <Input placeholder="Enter your text" $error={false} $disabled={false} />

 

html 자체적인 속성말고 개발자가 조건부스타일을 하기위해 프롭스를 내린거구나~ 하면 된다.

 

스타일 확장
const Button = styled.button`
  padding: 10px 20px;
// ...생략
`;

const PrimaryButton = styled(Button)`
  background-color: blue;
// ...생략
  }
`;

const SecondaryButton = styled(Button)`
  background-color: gray;
// ...생략
  }
`;

중복일 경우 소괄호 안에 넣어주면 된다.

공통된 스타일이 있으면 버튼 스타일드컴포넌트를 만들어놓고 위 코드처럼 (button)을 넣어서 확장할 수 있어야 한다.

 

 

 


react-router-dom 을 통한 라우터 처리

 

// 정적라우팅
	<Route path="/" element={<Home />} />
        <Route path="/detail" element={<Detail />} />
// path 파라미터
	<Route path="/" element={<Home />} />
        <Route path="/detail/:id" element={<Detail />} />

 

도메인/ paht   => 이런느낌! 즉 콜론 뒤에있는 게 변수다. 변수는 데이터를 받는 놈.

*  파라미터는 여러 개 받을 수 있다.

 


useEffect - 사이트이펙트 처

 

외부시스템과 컴포넌트를 동기화하는 react hook... 대체 뭔 소리인가 했다.

 

화면을 그리기위한 동기적인 코드들만 react 함수 컴포넌트  내에 존재할 수 있다.  이 외에 외부시스템 WEB API (setTimout, document.querySelector, addEventListner, fetch, localStroage)이랑 동기화하기 위해 쓴다.

 

렌더링 시 화면에 불필요 한 외부시스템이 있으면 사이드 이펙트가 생긴다.

그래서 사이드 이펙트가 될만한 것들은 useEffect 안에 써야 한다.

useEffect(()=>{
	// setup 함수 실행 시점
	// 1. 컴포넌트 마운트 이후 실행
	// 2. depenency array에 변화된 값이 있는 경우, 클린업 함수 이후에 실행
	
	return ()=>{
		// 클린업 함수 실행 시점
		// 1. 페이지 이동으로 인해 다른 컴포넌트가 마운트 된 후에 실행
		// 2. dependency array안의 값이 변경되었을 때 리렌더링 이후 곧바로 실행
	}
}, [state])

// return 위에 써라!!!

 

 


매일 읽고 암기 할 것.