오늘 한 일

  • 지금은 아니고 예전에, 동영상과 문서 파일을 업로드하는 기능을 한창 작업하고 있을 때였다. 파일을 올리면 화면에 첨부한 파일 리스트가 생성되고 그 리스트에서 파일을 지울 수가 있었는데, 파일 A를 올렸다가 지우고 다시 같은 파일을 올리려고 하면 먹통이 되곤 했다.
  • 사용자가 어쩌다 파일 하나를 올리고 실수로 지워버려서 다시 올리려고 한다면? 파일 A가 재차 첨부되지 않으므로, 임의로 파일 B를 첨부했다가 그 뒤에 파일 A를 첨부하고, 애초에 필요가 없는 파일 B를 다시 지워야 한다. 수고롭다...
  • onChange 이벤트를 통해 첨부된 파일을 감지하는데, 말 그대로 onChange이기 때문에 기존 상태와 다른 데이터가 들어가야지만 이벤트가 실행된다. 파일 A가 들어갔는데, 다시 똑같은 파일 A가 들어간다면 변화가 없으므로 아무런 일도 일어나지 않는다.

오늘 배운 것

  • onChange가 실행될 때마다 event.target.value에 빈 값을 주면 다음 순서로 똑같은 파일이 들어와도 변화를 감지할 수 있게 된다.
 

Input=file 에서 같은 파일 입력받기 - 짜구's WIKI

Input 태그를 통해서 파일을 입력받을 때 onChange 이벤트를 더하게 된다. 그런데 onChange는 실질적인 데이터가 바뀔때만 반응하므로 기존의 파일을 다시 업로드할 때는 이벤트가 작동하지 않으므로

wiki.jjagu.com

오늘 한 일

  • 회사 웹사이트 디자인이 다시 한 번 대변동을 일으켰다. 이번엔 싹 다 갈아엎는 수준까지는 아니어도, 세세한 부분까지 많은 변화가 있어서 하나하나 체크하면서 작업하려니 여간 수고롭지가 않다.
  • 형태는 똑같은 이미지인데 색상이 서로 묘하게 달리 적용된 것들도 꽤 있었다. 똑같은 알파벳으로 된 단어가 여기서는 옅은 연두색인데, 저기서는 좀 진한 초록색인 식. 일일이 svg로 저장하며 이미지 파일이 늘어나는 현상에 환멸을 느끼려던 찰나, 또 우연한 기회에 유용한 링크를 찾아냈다.
  • 방법인즉슨 이렇다. 해당 svg 파일을 열어서 fill='none'이나 fill='#000000' 같이 색상 코드가 들어간 부분을 fill='current'로 변경해준다.
  • 그리고 아래처럼 임포트하면 svg 파일일지라도 리액트 컴포넌트로서 가져와서 보통의 컴포넌트처럼 사용할 수 있다. 이렇게 가져온 컴포넌트에 fill 속성을 원하는 색상 코드로 넣어준다. 그러면 내가 원하는 색을 넣은 이미지로 바뀐다. 또, 마찬가지로 컴포넌트이기 때문에 일반적인 방식으로 style 속성을 넣으면 CSS의 인라인 적용도 가능하다.
import { ReactComponent as Blahblah } from '../your_directory/blahblah.svg';

...

  return (
      <Blahblah fill='#ffffff' style={{ margin: '10px' }} />
  )

오늘 배운 것

  • 어쩌다 찾게 됐는지는 기억이 잘 나지 않는다. 뭔가 다른 걸 찾으려고 시작한 구글링이었던 것 같은데 제목에 끌려서 그만..
 

How To Change SVG's Color in React.

Update SVG fill and stroke without the need of creating a react component for each image.

dev.to

오늘 한 일

  • 출근해서 맞닥뜨린 가장 첫 이슈였다. 댓글을 삭제하기 위해 서버로 DELETE 요청을 보내는데, 분명 형식에 맞춰 보냈는데도 왜인지 자꾸만 400 에러가 뜨고 오류의 원인은 쉽게 찾아지지가 않았다.
  • 400이 뜨는 만큼 내가 뭔가 잘못한 것 같기는 한데 명확한 에러 메시지도, 가늠해 볼만한 단서도 없어서 일단 구글링을 시작했다.
  • 찾아보니 DELETE에 request body를 보내도 되느냐를 가지고 제각기 말들이 많았다. 아니 근데 나도 body 보내는데...!?
  • 이것과 관련한 문제가 맞을 것 같은 예감이 들었고, 그러던 중 스택오버플로우에서 해결책을 찾았다.

오늘 배운 것

  • request body를 data라는 키를 붙인 객체로 만든다. {key: value} 이었다면 {data: {key: value}} 이런 식으로. 단순히 이걸로 해결된다니...
 

Axios Delete request with body and headers?

I'm using Axios while programing in ReactJS and I pretend to send a DELETE request to my server. To do so I need the headers: headers: { 'Authorization': ... } and the body is composed of var

stackoverflow.com

오늘 한 일

  • 현재 회사의 웹과 앱에 적용된 기능의 범위에 약간 차이가 있어서, 오늘은 그 차이의 간극을 메우는 작업을 했다. 앱에는 이미 있는 기능이지만 웹에서는 아직 구현하지 않은, 예를 들면 댓글 관련 기능 같은 것들을 붙여 보았다.
  • 앱에서 돌아가게 하느라 api는 이미 완성되어 있는 상황이라 나는 말 그대로 거기에 맞춰 구현하기만 하면 되는 거였다. (+ 디자인)
  • 기획안과 디자인에 따르면, 댓글을 작성할 수 있는 페이지에 처음 진입하면 댓글 입력란만 보이고 등록 버튼은 보이지 않는데 입력란을 클릭해서 커서를 띄우는 순간 한쪽에 등록 버튼이 생긴다. 다시 외부 요소를 클릭해 커서를 없애면 등록 버튼도 없어져 원래의 레이아웃으로 돌아간다.

오늘 배운 것

  • 해당 input 태그에 포커스가 맞춰져 있을 때 실행하는 함수는 onfocus 이벤트로 넣어준다. html이나 자바스크립트에서는 onfocus로 쓰지만, 리액트에서는 camel case로 onFocus라고 쓴다.
 

onfocus Event

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

  • onblur는 워낙 자주 썼는데도, onfocus의 반대의 경우를 생각하려고 하니 오히려 생각이 잘 안 났다. 그러다 위 링크 Definition and Usage 부분 3번째 줄에 적혀 있는 걸 보고서야 아차 싶었다. onfocus의 반대의 경우, 그러니까 포커스를 잃었을 때의 이벤트는 onblur로 넣는다. 리액트에서는 역시 onBlur.
The onfocus event is the opposite of the onblur event.
  • input 태그에 들어가는 커서를 cursor라고 하는 게 맞는지, CSS에서 쓰는 것처럼 caret이라고 하는 게 맞는지 확인해보려다 찾은 내용이다. caret-color는 그 커서의 색깔을 지정하는 CSS 속성인데, 아래 링크에 따르면 'insertion caret 또는 text input cursor라고도 하는 것의 색깔...'이라고 되어 있다.
 

caret-color - CSS: Cascading Style Sheets | MDN

The caret-color CSS property sets the color of the insertion caret, the visible marker where the next character typed will be inserted. This is sometimes referred to as the text input cursor. The caret appears in elements such as <input> or those with the

developer.mozilla.org

 

오늘 한 일

  • 2022년 새해가 밝았으니 새로운 마음으로 TIL을 적어본다. 느낌상 내일부터 또 다시 업무가 바빠질 것만 같지만, 일단은 그렇지 않을 것처럼 쓰겠다. 희망사항
  • 오늘은 새해 첫 출근이었던 만큼 물론 해야 할 일은 산처럼 쌓여 있지만 급히 작업에 착수하기보다는 지금까지 지난 3개월 간 작업해 둔 코드들을 돌아볼 수 있는 시간을 가졌다. 하지만 실제로 코드들을 처음부터 차근차근 뜯어볼 수 있었던 건 아니었다. 어쩌다 보니 존재조차 몰랐던 오류를 찾아버렸기 때문이었다!
  • 한 가지 기능을 아주 약간 개선해보려다 줄줄이 소세지마냥 이어지는 오류들 때문에 시간을 잡아먹었다. 아직 개선된 버전을 배포하지는 않았으므로 순식간에 배포해버릴 깡도 없고.. 완전히 처리한 건 아니지만 잠시나마 꼬리에 꼬리를 물고 나타나던 여러 오류들을 잡아놔서 마음이 조금은 편해졌다.

오늘 배운 것

  • 오늘은 가지고 있는 링크들 중 가벼운 걸로 풀어보겠다. 항상 이렇게 시작하곤 했지만 기분 탓이라고 하고 싶다. flex-wrap 속성은 display: flex 속성을 가진 부모 요소 안에 자식 요소들이 나열되어 있을 때 넓이와 상관없이 한 줄에 모두 보여줄 것인지, 나열된 자식 요소들의 총 넓이가 부모의 넓이를 초과할 때 초과한 자식 요소들을 다음 줄로 넘겨서 보여줄 것인지를 결정한다.
  • nowrap이면 한 줄에 모두 보여주고, wrap이면 다음 줄로 넘기고, wrap-reverse면 다음 줄로 넘기되 순서를 거꾸로 뒤집는 것이다.
 

flex-wrap - CSS: Cascading Style Sheets | MDN

The flex-wrap CSS property sets whether flex items are forced onto one line or can wrap onto multiple lines. If wrapping is allowed, it sets the direction that lines are stacked.

developer.mozilla.org

  • 정석은 물론 MDN 버전이겠지만, 한글로 된 설명은 이 블로그를 참고하면 좋을 것 같다.
 

CSS flex > flex-wrap 속성

flex-wrap 속성은 나열 된 (정렬 된) 요소들의 총 넓이가 부모 넓이 보다 클 때, 이 요소들을 다음 줄에 이...

blog.naver.com

오늘까지 한 일

  • 점점 TIL 쓰는 간격이 길어진다..ㅠㅠ연말 업데이트를 앞두고 퇴근 시간이 점점 늦어지는 와중에 체력이 받쳐주지 못하는 관계로 TIL 쓰는 걸 자꾸 미루다 보니 이렇게 되기에 이르렀다. 일하면서 찾아놓은 귀중한 링크들만 쌓여가고 풀지를 못하고 있다.. 그러니까 저질체력을 벗어나게 운동을 하자
  • 12월 업데이트를 제때 하기 위해 매일같이 야근을 하면서, 최근에는 기본 시스템 팝업창을 쓰지 않기 위한 커스텀 모달창을 제작했다. 모달을 띄워야 하는 페이지라면 어디에서든지 사용해야 하는 컴포넌트가 되므로, 그때그때 다른 속성들을 넘기기 위해 이런저런 props를 미리 정의해보았다. 그러는 과정에서 다른 모달 제작 사례들을 찾아봤고, props의 타입을 체크하는 방법을 리액트 공식문서를 통해 알게 되었다...! 공식문서 절대 놓지 말자
  • props의 타입을 미리 정해놓고 유효성 검사를 할 수 있게 되는데, 그렇게 하면 모달 컴포넌트에 props를 넘길 때 마치 외부 패키지를 갖다 쓰는 것처럼 vscode에서 알아서 미리 정의된 타입을 알려주는 툴팁을 띄운다. 와 뭐야 감동

오늘 그때 배운 것

  • 역시 공식문서! 두 번 보고 세 번 봅시다ㅠㅠ
 

Typechecking With PropTypes – React

A JavaScript library for building user interfaces

reactjs.org

  • 원리는 공식문서를 참고하되 이제는 내장함수가 아닌 패키지로 옮겨졌다고 하니 npm 링크도 함께 첨부합니다.
 

prop-types

Runtime type checking for React props and similar objects.

www.npmjs.com

오늘까지 한 일

  • 일단 우여곡절 끝에 1차 배포를 한 후, 열흘쯤 전에 회사에 보다 더 가까운 곳으로 이사를 했다. 이사 후 뒷정리는 해도 해도 끝이 없어서 본의 아니게 이사 후 일주일은 아주 칼퇴를 해버렸다.
  • 그러고 나서 주말에 좀 쉴까 했더니 우리집 고양이(라고 쓰고 읽을 땐 주인님)가 이사 후유증 때문인지 병을 얻으셔서 신경 쓰느라 주말도 순삭. 아니 다시 월요일이잖아!?
  • TIL 쓰는 건 고사하고, 일하면서 찾아낸 고귀한 링크들을 북마크만 해놓고 제대로 읽어보지도 못했다. 간단한 것이더라도 하나하나 차근차근 다시 풀어갈 생각이다.
  • 회사에서는 2차 배포를 준비하고 있다. 사실 지난 주에도 쉬어가는 느낌으로 중간 배포를 한번 했어야 했는데 어쩌다 보니 작업이 계속 완결되지가 않아서 흐지부지 되고 말았다. 이번주는 좀 더 치열하게 해보자, 하고 시작했는데 그것도 참 마음대로 되지 않는다. 시도 때도 없이 맞닥뜨리게 되는 이 에러들을 능숙하게 핸들링할 그날이 언젠가는 올까..?

오늘 이전에 배운 것

  • 오늘은 기억에 남아 있으면서 간단한 것부터 적겠다. 방법이야 정하기 나름이겠지만 클릭 같은 이벤트를 발생시키면 특정 텍스트를 클립보드에 복사하는 코드가 필요한 적이 있었다. 정확히 말하자면 내가 복사할 데이터는 브라우저 주소창에 들어가 있는 현재 페이지의 URL이었다. 페이지에 실제로 보여주지는 않을 가짜 input을 만들고 거기에 복사할 데이터를 넣은 다음, 그 데이터를 선택해서 복사한 후 만들었던 가짜 input은 바로 없애버리는 식으로 작동시키는 방법이다. 이 코드를 실행하고 나면 어디에 붙여넣기를 해도 내가 코드로 복사한 텍스트가 나온다.
 

Copy current URL to clipboard – JavaScript

Not sure why this has been so difficult for me today, but for some reason I cannot seem to get it to copy the current URL to the clipboard. Overall, I’m looking for a way to do it without needing to create some hidden text elements. This is what I’m tr

javascript.tutorialink.com

  • 근데 이걸 vscode에 입력하고 나면 자꾸만 경고창이 뜬다. Document.execCommand()가 존재하지 않는다고 했었나, 아무튼 쓸 수 없다는 것이다. 그래도 일단 작동은 하는데, MDN에 따르면 이미 적용되지 않는 브라우저가 있다고 한다. MDN의 Browser compatibility를 참고하면 클립보드로 복사하는 데 사용하는 copy command 정도는 아직 브라우저 상관없이 지원된다. 하지만 어쨌든 deprecated라는 것... 조만간 사용할 수 없게 되지 않을까 싶다.
 

Document.execCommand() - Web APIs | MDN

When an HTML document has been switched to designMode, its document object exposes an execCommand method to run commands that manipulate the current editable region, such as form inputs or contentEditable elements.

developer.mozilla.org

  • 그리고 MDN에서도 설명하듯이, execCommand 대신 Clipboard API를 사용하라고 한다. 아래 링크에서는 자바스크립트에서 제공하는 Clipboard API를 이용하는 방법을 설명한다. 하지만 이건 또 새롭게 등장한 방법이므로 역시 지원되지 않는 브라우저가 있고, 구버전은 당연히 지원하지 않는다. 현재로서는 execCommand와 Clipboard API를 병용하는 게 나을 것 같다.
 

Copy Text to Clipboard in JavaScript

In this article, we will introduce how to copy text to the clipboard in JavaScript.

www.delftstack.com

오늘 한 일

  • 아직도 오픈 못했다...dev 환경 배포 후 stage 환경 배포까지는 마쳤지만 production 배포를 못했다ㅠㅠ 이번 주 초반까지만 해도 별 어려움 없이 진행되지 않을까 싶었는데 꼬리에 꼬리를 무는 온갖 오류 덕분에 금요일까지 밀려버리고 말았다.
  • 각 환경마다 연결되어 있는 서버도 달라서 환경별로 서버 url도 달라지고, 실서비스에서는 보여주지 않아야 할 부분이나 작동하지 않아야 할 함수 같은 것들을 각각 분기할 필요가 있다.
  • 건드리는 게 금기시 된다고 아무도 얘기한 적 없는데 나만 그렇게 생각한 프로젝트 내 package.json 파일을 직접 건드려서 스크립트 명령어를 고치면 손쉽게 환경변수를 분기할 수 있다. 물론 환경변수만 분기했다고 끝나는 건 아니고, 그것이 각각 다르게 작동해야 할 파일들에는 직접 조건문을 사용하든지 해서 적용을 해줘야 한다.
  • 프로젝트 내부 어느 위치에서든지 process.env.NODE_ENV를 찍어보면 development나 production이 나오는데, 이건 디폴트가 development이고 내가 어떤 환경으로 의도했건 빌드 후 배포를 하면 production이 되는 것 같다.
  • 하지만 기능 테스트를 하기 위해 개발서버에 배포하고 싶을 수도 있고, production 직전에 동일한 환경을 만들어 최종 테스트를 하기 위해 개발환경도, 운영환경도 아닌 그 중간 어디쯤의 테스트 환경으로 배포하고 싶을 수도 있다. 하지만 배포하면 process.env.NODE_ENV는 production이 된다.
  • 환경을 내 마음대로 분기하기 위해서는 package.json에 'env': 'process.env.REACT_APP_<CUSTOM>=<SOMETHING> react-script start' 같은 형식으로 스크립트 명령어를 적어두고, 키보드가 닳을 정도로 입력하던 yarn start 대신 내가 만든 명령어를 넣어서 yarn env를 입력하면 REACT_APP_<CUSTOM>이 <SOMETHING> 모드로 실행된다. App.jsx에 현재 실행되고 있는 환경을 확인할 수 있는 로그를 찍는 함수를 넣어놓으면 좋다.
  • 아냐 이것보다 더 중요한 건 오늘 항해 4기분들 멘토링(내가 뭐라고 멘토링을...ㅠㅠ)이 있었다는 것이다! 배포 프로세스 밟다가 삐걱거려서 30분이나 지각한 데다 말주변도 없어서 이 말 저 말 다 주워 섬기는 내가 너무 민망할 정도로 많은 분들이 계셨다. 근데 그 분들이 리액트 거의 전체 인원이라는 게 함정...
  • 아무튼 내가 오늘 한 말들이 얼마나 실제로 도움이 되어 드릴 수 있는지는 모르겠지만 예전의 내 모습을 보는 것 같아 한편으로는 짠하고 한편으로는 기특(?)했다. 코딩에 한창 재미 느껴가며 스스로의 부족함도 깨달아가며 채찍질도 하고 모든 시간을 공부에 투자할 수 있다는 게 얼마나 좋았는지. 당시에는 잘 될 거다, 하면 된다, 어렵지 않다 같은 말들 코웃음 치며 한 귀로 듣고 한 귀로 흘렸는데 지금 생각해보면 그게 다 맞는 말이라는 것도 신기하다. 꼭 4기 분들도 나와 같은 기분을 느낄 수 있었으면 좋겠다. 아니 근데 벌써 4기라니 내 시간 다 어디 갔어

오늘 배운 것

  • 환경변수 분기에 대해 자세히 설명한 링크. 다만 나는 이 분이 사용하신 모듈 없이 package.json 명령어만 수정했다. 그걸로도 충분하다고 생각한다. 아직은
 

CRA 환경에서 배포 시 .env 분기하기 (feat. env-cmd)

배포환경이 dev 서버와 실서버가 구분되어 있을 때, 사용 하는 환경변수들을 다르게 설정해야 되는 경우가 있다.예를 들어 Api url 이 prodution 서버는 example.co.kr 이고, dev 서버는 dev.example.co.kr 일 수

velog.io

  • 이건 위 링크에 비하면 기본적인 내용이고 5년 전 게시글이지만 중요하다고 생각해서 가져왔다. package.json에 명령어 추가하고 사용하는 방법에 대한 짧은 스택오버플로우의 질답이다.
 

How do I add a custom script to my package.json file that runs a javascript file?

I want to be able to execute the command script1 in a project directory that will run node script1.js. script1.js is a file in the same directory. The command needs to be specific to the project

stackoverflow.com

+ Recent posts