로컬 러닝 트래커 구축

8478 단어 reactshowdev
우리 지역 러너 클럽은 4개월 동안 100마일을 달리는 도전 과제가 있습니다. 그들은 10x10 확인란 그리드의 PDF를 제공하여 러너에게 인쇄하고 완료된 각 마일을 확인하도록 지시했습니다. 내 반응은 백 투 더 퓨처 2의 녀석과 비슷했습니다.



나는 스스로 생각했습니다. 우리는 이 양식의 대화형 버전을 만들어야 합니다. 그래서 나는 했다. 최종 버전을 사용할 수 있습니다here. React로 작성되었으며 소스는 GitHub 에서 사용할 수 있으며 Netlify 에서 자동으로 배포됩니다.

앱 빌드



나는 create-react-app를 사용하여 이 웹앱의 스캐폴딩을 구축했습니다. 처음 해보지만 개츠비(그 자체가 리액트 프로젝트)로 사이트를 몇 개 만들어봤기 때문에 충분히 편했다.

CSS 프레임워크



최신 프로젝트에서는 Bootstrap 또는 Tailwind를 사용하는 것이 일반적입니다. 전자는 바로 사용할 수 있는 반면 후자는 도구가 조금 더 필요합니다. 나는 한동안 CodyFrame 라이브러리를 선호했습니다. 그리드 시스템은 부트스트랩만큼 사용하기 쉽기 때문에 기본 12열 대신 10열 너비로 사용자 지정했습니다.

100개의 체크박스



물론 100개의 그리드 열과 확인란을 복사하여 붙여넣을 수 있습니다. 그러나 JavaScript 내에서 전체 앱을 렌더링하는 이점 중 하나는 동적으로 반복하고 렌더링할 수 있다는 것입니다(어쨌든 백엔드 서버가 필요하지 않음). 그래서 제가 한 일입니다.

{Array.from(Array(100), (e, i) => {return (
  // simplified HTML 😉
  <input type="checkbox" id={`day-${i + 1}`} />
)})}


데이터 저장



이 앱이 데이터를 저장하지 않는 동시에 사용자가 진행 상황을 추적할 수 있도록 하는 것이 중요했습니다. 이를 달성하기 위해 데이터는 로컬에만 저장되며 로컬 스토리지 외부에는 데이터가 저장되지 않습니다. JavaScript에서는 다음과 같이 간단합니다.

localStorage.setItem(key, value);


로컬 저장소를 직접 수정하는 호출 수를 최소화하기 위해 이름 및 확인란의 변경 이벤트가 상태를 수정합니다. 이것은 또한 모든 속성이 JSON으로 로컬 저장소에 저장되도록 하기 위해 수행됩니다. 그런 다음 componentDidMountcomponentDidUpdate 함수는 로컬 저장소에서 가져오고 설정하는 것은 물론 JSON 형식을 구문 분석 및 문자열화(단어가 너무 많음)하는 일을 담당합니다. 예를 들어 이름 텍스트 상자의 모든 기능은 다음과 같습니다(단순화를 위해).

componentDidMount() {
  const nameJson = localStorage.getItem('name');
  if (nameJson) {
    const name = JSON.parse(nameJson);
    this.setState(() => ({ name }));
  }
}

componentDidUpdate(prevProps, prevState) {
  if (prevState.name !== this.state.name) {
    const name = this.state.name;
    localStorage.setItem('name', JSON.stringify(name));
  }
}

<input onChange={event => this.setState({ name: event.target.value })} />


DOM 노드를 이미지로 내보내기



내가 생각하기에 아주 멋지다고 생각한 것은 자신의 진행 상황에 대한 이미지를 생성(및 다운로드)하는 기능입니다. 나는 서버 측에서 Java로 이미지를 생성하는 데 약간 손을 대었지만 클라이언트 측 앱에서는 결코 하지 않았습니다. 검색을 통해 dom-to-image 을 찾았습니다. 여기에는 JPEG, PNG 또는 blob(킬러 종류가 아님, "blob"은 raw file data)으로 내보내는 옵션이 있으며 원하는 대로 읽거나 처리할 수 있습니다. ). 다른 라이브러리와 결합하여 make saving files easier 이미지를 쉽게 내보낼 수 있습니다.

domtoimage.toBlob(document.getElementById('main'), {
  bgcolor: '#ffffff',
}).then(function (blob) {
  saveAs(blob, '100-miles.png');
});


시행 착오를 통해 이미지의 배경색을 수동으로 설정해야 한다는 것을 배웠습니다. 또한 dom-to-image의 문서에 따라 Safari가 지원되지 않는다는 사실도 발견했습니다. (이는 iPhone을 의미하기도 합니다.) 이 특정 문제는 원클릭 이미지 다운로드를 방지할 수 있지만 앱의 기본 의도가 사용되는 것을 방지하지는 않습니다. 반응형이므로 모든 장치에서 사용할 수 있으며 모든 사용자가 어쨌든 스크린샷을 찍을 수 있습니다.

앱 배포



저는 전적으로 정적인 클라이언트 측 앱이라는 의도로 이 글을 썼기 때문에 Netlify에 배포하는 것이 저에게 가장 적합했습니다. 그들은 모든 git 사이트를 배포하기 위한 훌륭하고 쉬운 프로세스를 가지고 있습니다. 소스를 GitHub에 올렸기 때문에 전체 프로세스가 이보다 쉬울 수 없었습니다.

최종 제품!



좋은 웹페이지 즐겨찾기