React Study(3) ~ 세계시계를 만들어 보자

18514 단어 초보자React

세계 시계 만들기



여기까지 샘플 프로그램을 움직이는 것만 왔으므로, 지금 있는 지식으로 만들 수 있는 것들을 우선 하나 만들어 봅시다.
드롭다운이 있고 거기서 타임 존을 선택하면, 그 타임 존의 시계가 표시되어 초를 새기는 심플한 세계 시계를 만들어 봅니다.

프로젝트 만들기



우선은 create-react-app로 베이스를 만듭니다. 명령 통로에서 자주 기다립니다.

create-react-app
c:\projects>npx create-react-app react_watch
(省略)
We suggest that you begin by typing:

  cd react_watch
  npm start

Happy hacking!

c:\projects>

여기까지는 거의 템플리. 여기에서 src/App.js를 만나십시오. 사실은 제대로 컴포넌트화하는 편이 좋다는 것을 잘 보지만, 우선 App.js에 전부 써 버립니다.

화면 구성



완성계는 이런 느낌입니다. 스타일도 아무것도 없고 매우 똑같은 화면이지만 신경 쓰지 않습니다.

  • 현재 시간
  • 시간대
  • 시간대 선택기

  • 부품은 이것뿐입니다. 움직임으로서는 타임 존의 셀렉터를 움직이면 그 타임 존의 시간을 표시해 준다. 이것뿐입니다.

    화면 부품



    먼저 화면 파트용 부품을 준비합니다. 라고 말해도 셀렉터용 option의 배열과 아무리 아무것도 마진이 없는 화면도. . . 그래서 미안 정도의 style입니다.

    App.js
    const WatchComponent = () => {
    
      // 時間
      const date = new Date();
    
      // 最低限のスタイル…
      const style = { margin:"10pt" };
    
      // 選択できるタイムゾーン
      const timeZones = [
        {id:1, zone:"Asia/Tokyo"},
        {id:2, zone:"Europe/London"},
        {id:3, zone:"America/New_York"}
      ];
    
      // タイムゾーンをoptionタグに変換しておく
      const SelectItems = timeZones.map((item)=>{
        return (
          <option value={item.zone} key={item.id}>{item.zone}</option>
        )
      });
    

    나중에 좋아하게 타임 존을 늘릴 수 있도록 option 태그를 쓰지 않고 배열에 넣고, map 함수로 돌려 option 태그로 변환하고 있습니다.

    상태 저장



    상태는 선택되고 있는 타임 존, 지금의 시간. 이 두 가지입니다.

    App.js
      // 初期は日本時間
      const [selectedTimeZone, setTimeZone] = useState(timeZones[0].zone);
    
      // 初期表示は日本時間の今
      const [dispTime, setTime] = useState(date.toLocaleString('en-US',{ timeZone: selectedTimeZone }));
    
      // selectが選択された時の挙動
      const handleChange = (e) => {
        // タイムゾーンを選択されたものにする
        setTimeZone(e.target.value);
      };
    

    useState를 사용해 2개의 상태를 선언합니다. 각각 selectedTimeZone, dispTime입니다.
    셀렉터가 선택되었을 때에 타임 존을 재설정하는 handler도 선언해 둡니다.

    초당 화면 업데이트



    음, 시계 앱이므로 초당 화면을 업데이트하고 싶으므로 useEffect에서 setInterval로 타이머를 만듭니다. 클린업 함수로 그 타이머를 삭제하는 처리도 잊지 않고.

    App.js
      const callbackFunction = () =>{
        // 1000ミリ秒ごとにsetTimeしなおす
        const timer = setInterval(
          () => {
            setTime(new Date().toLocaleString('en-US',{ timeZone: selectedTimeZone }));
          }
          ,1000);
        return () => {
          clearInterval(timer);
        };
      };
    
      // 時間・タイムゾーンに変更があったら呼び出し
      useEffect(callbackFunction,[selectedTimeZone,dispTime]);
    

    타임 존이 변경되거나, 표시 시간이 바뀌면 또 1초 기다려 재묘화를 반복하고 있습니다. 매초 callbackFunction을 재작성하는 움직임이 될까? 여기 성능을 향상시키기 위해 useCallback을 사용하는 것처럼 보입니다.

    시계 표시



    이것으로 부품은 갖추었으므로 나머지는 표시만.

    App.js
      return (
        <>
          <div style={style}>
            <div>{dispTime}</div>
            <div>{selectedTimeZone}</div>
            <select value={selectedTimeZone} onChange={handleChange}>
              {SelectItems}
            </select>
          </div>
        </>
      );
    

    이제 안전하게 시계가 표시되었습니다.

    소스 전체



    소스 전체를 붙여 넣습니다. 솔직히 React云々가 아니라 자바스크립트로 수정해야 할 점이 많다고 생각합니다만, 학습 며칠에 이 적은 코드량으로 인터랙티브한 페이지를 간단하게 할 수 있는 것은 React의 힘일까라고 느꼈습니다.

    App.js
    import React, {useState,useEffect} from "react";
    
    const WatchComponent = () => {
    
      // 時間
      const date = new Date();
    
      // 最低限のスタイル…
      const style = { margin:"10pt" };
    
      // 選択できるタイムゾーン
      const timeZones = [
        {id:1, zone:"Asia/Tokyo"},
        {id:2, zone:"Europe/London"},
        {id:3, zone:"America/New_York"}
      ];
    
      // タイムゾーンをoptionタグに変換しておく
      const SelectItems = timeZones.map((item)=>{
        return (
          <option value={item.zone} key={item.id}>{item.zone}</option>
        )
      });
    
      // 初期は日本時間
      const [selectedTimeZone, setTimeZone] = useState(timeZones[0].zone);
    
      // 初期表示は日本時間の今
      const [dispTime, setTime] = useState(date.toLocaleString('en-US',{ timeZone: selectedTimeZone }));
    
      // selectが選択された時の挙動
      const handleChange = (e) => {
        // タイムゾーンを選択されたものにする
        setTimeZone(e.target.value);
      };
    
      const callbackFunction = () =>{
        // 1000ミリ秒ごとにsetTimeしなおす
        const timer = setInterval(
          () => {
            setTime(new Date().toLocaleString('en-US',{ timeZone: selectedTimeZone }));
          }
    
          ,1000);
        return () => {
          clearInterval(timer);
        };
      };
    
      // 時間・タイムゾーンに変更があったら呼び出し
      useEffect(callbackFunction,[selectedTimeZone,dispTime]);
    
      return (
        <>
          <div style={style}>
            <div>{dispTime}</div>
            <div>{selectedTimeZone}</div>
            <select value={selectedTimeZone} onChange={handleChange}>
              {SelectItems}
            </select>
          </div>
        </>
      );
    };
    
    export default function App() {
      return <WatchComponent />;
    }
    

    좋은 웹페이지 즐겨찾기