React Day 4

심재원·2023년 11월 9일
2

1교시(Calculator setting)

git clone https://github.com/h662/cra-tailwind-template.git calculator

cd calculator

npm install

npm run start

2교시(Calculator 시작)

import { useState } from "react";

const CalInput = () => {
  const [result, setResult] = useState("0");

  return (
    <input
      className="px-4 py-2 text-xl text-right w-full rounded-xl focus:outline-pink-400"
      type="text"
      value="0"
    />
  );
};

export default CalInput;

setResult를 통해서 result 관리해 줌

setResult : 함수
Result : 변수
Usestate : 위 변수 함수를 묶은 것

3교시

callinput 이 정보를 여전히 받는데 .. 상태관리 useState 부분을 부모인 App에 준다?.. 그래서 import를 App에서 해야한다..
다른 애들도 쓰려고 하니까 부모에게 올려준 것

Components/CalInput.jsx

const CalInput = ({ result, setResult }) => {
  const onChangeResult = (e) => {
    setResult(e.target.value);
  };

  return (
    <input
      className="px-4 py-2 text-xl text-right w-full rounded-xl focus:outline-pink-400"
      type="text"
      value={result}
      // onChange={onChangeResult}
    />
  );
};

export default CalInput;

Components/CalNumberBtn.jsx

const CalNumberBtn = ({ result, setResult, number }) => {
  const onClickNumber = () => {
    if (result == "0") {
      setResult(number);
    } else {
      setResult(result + number);
    }
  };

  return (
    <button className="btn-style" onClick={onClickNumber}>
      {number}
    </button>
  );
};

export default CalNumberBtn;

If else 써서 구현하는 코드

Components/CalDelBtn.jsx

const CalDelBtn = ({ result, setResult }) => {
  const onClickDel = () => {
    setResult(result.substring(0, result.length - 1));
  };

  return (
    <button
      className="btn-style bg-purple-500 active:bg-purple-700"
      onClick={onClickDel}
    >
      Del
    </button>
  );
};

export default CalDelBtn;

4교시

== : 값만 비교하는 것
Ex) 1 == ‘1’ true
: 값만 같으면 타입 상관없이 트루 출력

=== : 엄격하게 값과 타입 둘다 비교하는 것
1 === ‘1' false
: 값이랑 타입이랑 둘다 같아야 함.

import { useState } from "react";
import CalInput from "./components/CalInput";
import CalNumberBtn from "./components/CalNumberBtn";
import CalDelBtn from "./components/CalDelBtn";

const App = () => {
  const [result, setResult] = useState("0");
  const [temp, setTemp] = useState();
  const [operator, setOperator] = useState("+");

temp는 임시저장공간

5교시

isNaN("a"); -> true
isNaN("1"); -> false

Not a Number
: false가 나와야 숫자
: true가 뜨면 숫자가 아니라는 것

ex)

 const onClickOperator = () => {
    if(isNaN(result)) {
      alert("숫자를 입력하세요.");
    } else {
    setTemp(result);
    setResult("0");
    setOperator(inputOperator);
  }
  };

-> 숫자가 아니면 "숫자를 입력하세요" 팝업이 뜸

6교시

Calculator Vercel 배포

https://calculator-react-orpin-three.vercel.app/

7교시

use-effect-practice

console에 Hello, useEffect 두 번 뜨는 이유는
index.js에서 </React.StrictMode>가 디버깅을 하기 때문.
배포할 때는 </React.StrictMode>가 알아서 사라짐.

의존성 배열

import { useEffect, useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`현재 count 값 : ${count}`);
  }, []);

  return (
    <div className="bg-red-100 text-center">
      <button onClick={() => setCount(count - 1)}>-</button>
      <span className="mx-4">{count}</span>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
};

export default App;

[] 추가해줘서 재렌더링 될 때는 실행이 안 되고 있다.

useEffect(() => {
console.log(현재 count 값 : ${count});
}, []);

의존성 배열 포함해서 useEffect를 쓴다 정도로 알아두면 됨

그럼 왜? 이게 의존성 배열인가?

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`현재 count 값 : ${count}`);
  }, [count]);

useEffect의 값이 [] 배열에 들어오기 때문.
[]에 변수를 넣을 수 있음
만약 count를 [count] 넣어주게 되면 count값의 변화를 감지할 때마다
렌더링을 함. 이 값에 의존해서 이 함수가 실행이 되는 것. useEffect가 count 값을 추적하고 있는 것.

useEffect는 렌더링될 때 실행되는 함수이고,
의존성 배열은 useEffect가 실행되는 조건을 담는 배열

  • 렌더링이란?
    서버로부터 HTML 파일을 받아 브라우저에 뿌려주는 과정이다. 브라우저는 서버로부터 HTML 문서를 다운 받는다. 렌더링 엔진은 HTML 문서를 파싱해서 DOM 트리를 만든다. 그 다음, 외부 css 파일과 함께 포함된 스타일 요소를 파싱하여 CSSOM 트리를 만든다.
    -> 화면에 내용을 뿌리는 것

  • 파싱이란?

    <출처 : https://hengbokhan.tistory.com/134>

Q.

useEffect(() => {
    console.log("Hello, useEffect");
  },[]);

  useEffect(() => {
    console.log(count? ${count});
  },[count]);


이렇게 둘 다 사용할 경우, 
위의 Hello, useEffect"는 처음 화면 로딩 시에만 나오는데 
또 어떤 경우에 사용될까요?
복사해서 붙이니 백틱이 사라졌습니다.

A.

useEffect(() => {
    if (count === 0) {
      console.log("Hello, useEffect");
    } else {
      console.log(`count? ${count}`);
    }
  }, [count]);

8교시

Weather API

https://openweathermap.org/

로그인 후 my api key에서 API Key name 'weather' 이름으로 생성
키는 타인에게 노출 안 되게 조심할 것.

https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid={API key}
-> api key 입력해서 확인

크롬 console에서 아래 입력

navigator.geolocation.getCurrentPosition((position) => {
    console.log(position);
});

하고 나면 latitude와 longitude 확인 후 위 주소의 lat & lon 수정

사이트가 보기 불편하면 Chrome extension 'JSON viewer' 설치
https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh?hl=ko

그러면 보기 편하게 나옴!

그 후 npm install axios 터미널에 입력

코드 다음과 같이 입력

import axios from "axios";
import { useEffect, useState } from "react";

const App = () => {
  const [weatherData, setWeatherData] = useState();

  const getWeather = async () => {
    const response = await axios.get(
      "https://api.openweathermap.org/data/2.5/weather?위도&경도&API KEY"
    );

    setWeatherData(response.data);
    console.log(response.data);
  };

  useEffect(() => {
    getWeather();
  }, []);

  return (
    <div className="bg-red-100">
      {weatherData ? (
        <img
          src={`https://openweathermap.org/img/wn/${weatherData.weather[0].icon}@2x.png`}
        />
      ) : (
        <div>로딩중...</div>
      )}
    </div>
  );
};

export default App;

npm run start 후 날씨 그림 확인

0개의 댓글