thumbnail
State 끌어올리기 - RGB 색상 코드 변환기 만들기
Feb 14, 2023

리액트 State 끌어올리기로 색상 코드 변환기를 만들어보자.

State 끌어올리기

동일한 데이터의 상태를 여러 컴포넌트에서 사용하고 싶다면 해당 컴포넌트들의 공통 부모 컴포넌트로 state를 끌어올리는 것이 좋다. 아래 예시를 보며 차근차근 따라가 보자.


Converter

본문에서 설명할 예시는 RGB 코드를 HEX로, HEX 코드를 RGB로 변환시키는 색상 코드 변환기이다. 따로 convert 버튼을 누르지 않고 입력하는 즉시 변환된 코드를 보여주도록 할 것이다.

check list

RGB to HEX 변환

HEX to RGB 변환

색상 코드 변환 동시 처리

해당 색상을 보여주는 배경


코드 변환 함수

먼저 RGB와 HEX를 서로 변환하는 함수가 필요하다. RGB는 Red, Green, Blue를 0 ~ 255 사이의 숫자로 표현하여 혼합해 나타내는 방식이고 HEX는 # 기호 뒤에 16진수를 사용하여 나타내는 방식이다.

RGB VS HEX

RGB to HEX

RGB를 HEX로 바꾸는 함수는 인자로 받은 문자열을 배열로 변환시킨 후, 각 인덱스를 16진수로 변환시킬 것이다. 예를 들어 rgb(255, 255, 255)는 255를 16진수로 변환한 값 ‘ff’가 세 번 합쳐진 #ffffff가 된다.


숫자가 아닌 값이 입력되면 빈 문자열을 리턴하고 255 이상의 숫자가 입력되면 항상 ‘ff’로 변환되도록 한다.

const convertToHEX = (rgb) => { // 배열로 변환 후 숫자 타입으로 변경 const hexCode = rgb.split(',').map((x) => Number(x)); const result = []; for (let i = 0; i < 3; i++) { if (Number.isNaN(hexCode[i])) return ''; if (hexCode[i] > 255) { result.push('ff'); continue; } // ... } };

배열로 변환한 rgb(=hexCode)를 순회하면서 16진수로 변환한다. 이때, 16진수로 변환한 값이 한 자릿수라면 앞에 0을 추가한다. 최종적으로 전체 배열 요소를 합친 hex 코드를 리턴한다.

const convertToHEX = (rgb) => { // ... for (let i = 0; i < 3; i++) { //... hexCode[i].toString(16).length === 1 ? result.push(`0${hexCode[i].toString(16)}`) : result.push(hexCode[i].toString(16)); } return result.join(''); };

HEX to RGB

HEX를 RGB로 바꾸는 함수는 인자로 받은 16진수 문자열을 2글자씩 끊어 10진수로 변환시킬 것이다. #ffffff인 경우, ‘ff’를 10진수로 변환한 값 255를 [255, 255, 255] 형태로 반환한다.

그리고 똑같은 글자가 2개씩 연이어 형성된 hex는 3글자로 축약할 수 있는데, 이 점도 함께 고려하도록 한다.

ex) #ff00ff = #f0f / #aabbcc = #abc

const convertToRGB = (hex) => { let rgbCode = hex.split(''); let arr = []; // hex 코드가 3글자일 때, 글자 당 동일한 값을 해당 인덱스 뒤에 추가 if (rgbCode.length === 3) { hex.split('').map((x, i) => rgbCode.splice(2 * i + 1, 0, x)); } // 두 글자씩 끊어 10진수로 변환 for (let i = 0; i < 6; i += 2) { if (Number.isNaN(parseInt(`${rgbCode[i]}${rgbCode[i + 1]}`, 16))) return ''; arr.push(parseInt(`${rgbCode[i]}${rgbCode[i + 1]}`, 16)); } return arr; };

컴포넌트 구성

state를 관리할 부모 컴포넌트를 생성한다. 해당 컴포넌트는 state를 끌어올린 조상 격으로, 하위 컴포넌트들에 state를 공유하여 서로 동기화될 수 있게 한다.

state 관리

Converter 컴포넌트는 하위 컴포넌트로 rgb input과 hex input을 포함한다.

scalecode state를 생성한다. scale은 동작할 컴포넌트를 구분하는 상탯값이고 code는 rgb 또는 hex 코드를 나타내는 상탯값이다. 하위 컴포넌트들을 구분할 scale을 각각 지정해준다.

export default function Converter() { const [scale, setScale] = useState('hex'); const [code, setCode] = useState('537fe7'); return ( <div> <div> <p>RGB, HEX 색상 코드 변환</p> <ColorCodeInput scale="hex" /> <ColorCodeInput scale="rgb" /> </div> </div> ); }

그리고 각 컴포넌트에 맞는 코드를 전달한다. HEXRGB는 다른 컴포넌트에서 값이 변경되었을 때 해당 컴포넌트에 반영할 값이다. 배경색도 변경된 값을 반영하기 위해 style 속성을 설정해준다.

export default function Converter() { // ... const HEX = scale === 'rgb' ? convertToHEX(code) : code; const RGB = scale === 'hex' ? convertToRGB(code) : code; return ( <div style={{ backgroundColor: `#${HEX}` }}> <div> <p>RGB, HEX 색상 코드 변환</p> <ColorCodeInput scale="hex" code={HEX} /> <ColorCodeInput scale="rgb" code={RGB} /> </div> </div> ); }

마지막으로 상탯값을 변경할 on...Change 함수도 생성한다. input 값이 변경되면 code state 값도 변경되어 다른 컴포넌트와 동기화가 가능하게 된다.

export default function Converter() { // ... const handleHEXChange = (code) => { setScale('hex'); setCode(code); }; const handleRGBChange = (code) => { setScale('rgb'); setCode(code); }; return ( <div style={{ backgroundColor: `#${HEX}` }}> <div> <p>RGB, HEX 색상 코드 변환</p> <ColorCodeInput scale="hex" code={HEX} onCodeChange={handleHEXChange} /> <ColorCodeInput scale="rgb" code={RGB} onCodeChange={handleRGBChange} /> </div> </div> ); }

input 컴포넌트

ColorCodeInput 컴포넌트는 부모 컴포넌트 Converter로부터 넘겨받은 props를 input에 전달한다. scale로 라벨에 전달할 이름을 설정하고 state 변경은 setState() 대신에 props로 받은 onCodeChange를 호출하도록 한다.

const CodeNames = { hex: 'HEX', rgb: 'RGB', }; const ColorCodeInput = ({ scale, code, onCodeChange }) => { return ( <div> <label>{CodeNames[scale]}</label> <input value={code} onChange={(e) => onCodeChange(e.target.value)} /> </div> ); }; export default ColorCodeInput;

결과

Result


구현한 코드가 동작하는 과정을 간단하게 정리해보면,

🎯 코드 동작 과정

  1. <input>의 onCodeChange를 호출한다. onCodeChange는 handle...Change 함수에 해당한다.

  2. handle...Change 함수는 Converter 컴포넌트가 변경된 입력값과 수정한 input의 식별 코드(=scale)를 setState()를 호출함으로써 react에 다시 렌더링하도록 요청한다.

  3. Converter 컴포넌트의 return()이 호출되면서 rgb to hex 또는 hex to rgb 변환이 일어난다.

  4. ColorCodeInput 컴포넌트의 return()이 호출된다.

  5. DOM이 갱신되어 변경된 값이 화면에 나타난다.

이렇게 색상 코드 변환기를 통해 state 끌어올리기를 학습해 보았다.


References

Table Of Contents
nxnaxx blog © 2022-2024 Powered By Gatsby.