반응형

Sketch

 

가장 초창기에 나온 전통적인 디자인 툴

(Sketch는 맥OS에서만 사용가능)

Sketch는 클라우드 서버를 제공하고 로컬 저장 가능

Sketch는 클라우드 스토리지 서비스를 이용해 다른 사용자와 파일을 공유하고 편집할 수 있는 기능을 제공하나 실시간 협업 방식은 아니다.

 

Figma (디자이너 툴 - 가장 추천)

협업을 위한 디자인 툴(2021년 기준 선호도 1위)

 

프레이밍 전략: 디자인이 아닌 협업에 초점

여러 사람이 웹에서 실시간으로 동시 작업하는 모습을 강조

 

장점

 

웹 기반 동시에 아트보드 편집 -> 디자이너가 작업하는 동안 개발자가 기다리는 병목 현상 X

디자인의 css 그대로 copy 가능

 

단점

인터넷이 필수 -> 보안 문제 발생 가능

한글 관련 자잘한 버그

 

디자인 시스템 (방법론)

그림 1) 라인의 디자인 시스템 예시

 

개발자 사이에 협업을 위해서 그라운드 룰로 컨벤션을 정하듯이 디자이너 <=> 개발자,

혹은 디자이너끼리 커뮤니케이션 하기 위해서 정해놓은 방법론

 

도입 이전의 문제 제기

 

일관되지 않은 디자인 -> 제품의 사용성을 떨어트림

비효율적인 작업 -> 동일 코드 & 디자인의 중복 작성 문제

확장성 부족 -> 로직에 집중해야할 시간을 UI에 집중

 

해결 방안

 

정해진 디자인 패턴 & 컴포넌트를 재사용해 제품을 구축하여 사용자 입장에서 일관되고 차별화된 경험을 하도록 하는 가이드라인

개발자 입장에서 제품을 구축할때 컴포넌트를 재사용해서 구축 & 개선하는데 걸리는 시간 단축

 

구현 해놓으면 이후엔 재사용으로 작업 속도가 빨라질것이라 예상 가능

시스템 자체가 중요한게 아니라 쓸만한 “룰”이 중요

 

예시 사례)

Figma - material UI(https://www.figma.com/file/aNN74suNWBb0uFGW3lxV7Q/Material-Me-(preview)?node-id=10276%3A257885)

Figma - buzzvil (https://www.figma.com/file/oWpE6CAuRW9fdCRziPGrnu/Apps--—-Buzzvil-Design-System-(Community)?node-id=4809%3A183)

 

storybook (개발 툴)

컴포넌트 단위의 UI 개발 환경을 지원하는 도구

 

주 사용 목적

개발된 컴포넌트의 문서화

개발 작업물 공유(개발자<->개발자, 디자이너 등)

협업시 다른 사람들에게 현 'context' 공유가 주 목적

내가 아닌 남을 위한 작업

반응형
반응형

태그

 

Map tag

HTML CSS JavaScript MDN infographic

 

HTML <map> 요소 <area> 요소와 함께 이미지 맵(클릭 가능한 링크 영역)을 정의할 때 사용

 

https://developer.mozilla.org/ko/docs/Web/HTML/Element/map

 

속성 

role

 

<!-- role example -->
<li role="menuitem">Open file…</li>

Role 은 HTML 요소의 역할을 약속

기본 tag만으로 해당 요소의 역할을 정의하기 어려울때 사용

 

        <div role="button">Place Order</div>

해당 <div>의 작성자가 버튼에 기대되는 키보드 인터랙션을 제공하는 JavaScript도 구현했다는 약속

(반대로 아래에서 설명할 ARIA 역할(role)은 브라우저가 키보드 동작이나 스타일링을 제공하지 않습니다.)

 

 

area 계열

 

속성 (Property) 는 해당 요소의 특징이나 상황을 정의하며 aria- 라는 접두사를 사용

 

 

 

aria-label

<button aria-label="menu" class="button"></button>

aria-label 은 우리가 흔히 알고 있는 Label 목적을 위한 속성

특정 요소에 대한 설명을 그대로

 

 

... 공부하는대로 계속 업데이트중 

 

 

CSS들 

 

https://www.notion.so/css-851342264b4c4bde9f96a6f8f8e765bf

 

 

 

 

reference

 

https://bcp0109.tistory.com/348

 

웹 접근성과 WAI-ARIA

Overview HTML 페이지를 만들 때 고려해야 하는 것 중 하나가 웹 접근성입니다. 웹 접근성이란 시각장애인들이 웹 페이지를 원활하게 이용할 수 있도록 알려주는 가이드라인이라고 생각하면 됩니다

bcp0109.tistory.com

https://mulder21c.github.io/aria-practices/

 

WAI-ARIA 작성 방법 1.2

유저 인터페이스가 적절한 접근 가능한 이름을 제공하는데 사용될 수 있는 보이는 텍스트를 포함하는 경우, 접근 가능한 이름에 대한 보이는 텍스트를 사용하는 것이 유지보수를 간소화하고,

mulder21c.github.io

 

반응형
반응형

tabIndex

 

tabIndex 전역 특성은 요소가 포커스 가능함을 나타내며,

Tab키를 사용한 연속적인 키보드 탐색에서 어느 순서에 위치할지 지정해준다.

 

tabIndex는 3개의 상태를 가진다.

 

음의 정수값 : 연속 키보드 탐색(이하 tab)으로 접근할 수 없는 값

 

0 : tab을 사용해 접근할 수 있는값, 위에서 아래 순서대로 접근 가능해짐

 

양의 정수값 : tab을 사용해 접근 가능하며 숫자가 큰 순서대로 우선순위가 정해진다. 최대값은 32767이다.

0부터 시작해서 다음에 1이 있고, 그다음 2가 되고 이런 식이다.

 

대화형 컨텐츠(<a>, <button>, <details>, <input>, <select>, <textarea> 등)은 tabIndex의 기본값이 0이고,

비대화형 컨텐츠(div 등)은 기본값이 -1이라 지정 해주지 않으면 tab키로 접근하지 않는다.

 

예시)

 

tabIndex test

1
2
10
1

(tistory에서 다른 tab때문에 엉키게 보임)

 

코드) 

 

<h2>tabIndex test</h2>
<div>
   <div>1</div>
   <div tabindex="3">2</div>
   <div tabindex="1"> 10</div>
   <button tabindex="2" type="button">abc</button>
   <div>1</div>
</div>

 

tabIndex를 임의대로 사용하면 사용자 입장에서 의도치 않은 결과를 낼 수 있는것 같으니

가능하면 양수 값 사용은 자제하는게 좋을 것 같다.

 

modal 열릴때 다른 곳 tab focus 방지를 위해 tabIndex를 활용하면 좋다는데

이건 한번 써보고 이어 쓰기로.. 

 

reference 

 

https://developer.mozilla.org/ko/docs/Web/HTML/Global_attributes/tabindex

 

tabindex - HTML: Hypertext Markup Language | MDN

tabindex 전역 특성은 요소가 포커스 가능함을 나타내며, 이름에서도 알 수 있듯, 주로 Tab 키를 사용하는 연속적인 키보드 탐색에서 어느 순서에 위치할지 지정합니다.

developer.mozilla.org

 

https://mygumi.tistory.com/53

 

웹 접근성 tabindex 속성 :: 마이구미

이번 글은 tabindex 속성에 대한 웹 접근성에 대해 알아볼 것이다. 참고 자료 - http://nuli.navercorp.com/sharing/blog/post/1132726 tabindex 를 활용한 하나의 테크닉 - https://mygumi.tistory.com/372 tab..

mygumi.tistory.com

 

반응형
반응형

박스의 width와 height를 어떻게 구하는지 정하는 방식

 

box-sizing = content-box | border-box | initial | inherit

 

값 

content-box 기본값. width와 height가 콘텐츠 영역만 포함하고 안팎 여백 & 테두리를 포함하지 않는다
border-box width와 height가 안팎 여백 & 테두리를 포함한다. 
initial 초기 값으로 지정 
inherit 부모로부터 상속

 

예제

 

border-box

content-box

 

 

<!DOCTYPE html>
<html>
<head>
<style> 
div.container {
  width: 100%;
  border: 2px solid black;
}

.content-box {
  box-sizing: content-box;
  width: 50%;
  border: 5px solid red;
  float: left;
}

.border-box {
  box-sizing: border-box;
  width: 50%;
  border: 5px solid red;
  float: left;
}


</style>
</head>
<body>

<div class="container">
  <div class="border-box">border-box</div>
  <br>
  
  <div class="content-box">content-box</div>
  <div style="clear:both;"></div>
</div>

</body>
</html>

 

가로 세로 길이의 정확한 값을 원하면 border-box 설정을 해두자 

 

reference 

 

https://www.w3schools.com/cssref/css3_pr_box-sizing.asp

반응형

'Front-end > CSS' 카테고리의 다른 글

font-family 상속 시키기  (0) 2022.11.04
css 챌린지  (0) 2022.10.05
[CSS] Gap  (0) 2022.06.13
loading spinner  (2) 2022.02.13
CSS 애니메이션 성능 개선  (0) 2022.01.27
반응형

props drilling을 줄이고 사용하는 입장에서 '조합'해서 사용할 수 있도록 하는 패턴 

 

예를 들어 

아래와 같은 코드가 있고, 내부적으로 2~4단계의 트리 depth단계로 구성된 컴포넌트가 있다면

<Counter text="example" ex1={<div></div>} onchange{()=>{ console.log(change)}} onClick={() => console.log('test1')}>

 

사용하는 입장에서는 내부 구성을 정확하게 알 수 없을것이다.

그래서 사용자 입장에서 컴포넌트를 직접 조합해서 구현하고 props를 직접 내려주는 방식이다.

 

코드 예시)

export default function AppEx() {
  return (
    <div>
      <Counter onClick={() => console.log('test1')}>
        <Counter.Increment />
        <Counter.Decrement />
        <Counter.Label />
      </Counter>

      <Counter onClick={() => console.log('test2')}>
        <Counter.Increment />
        <Counter.Label color="blue" />
        <Counter.Decrement />
      </Counter>

      <Counter onClick={() => console.log('test3')}>
        <Counter.Increment />
        <Counter.Label color="red" />
      </Counter>
    </div>
  );
}

 

구현된 화면 예시

 

장점 

 

매우 높은 유연성

선언적으로 구성 -> 가독성이 좋음 

하나의 giant component를 쪼개 여러개로 분리함으로써 복잡성이 줄어듬 

 

단점

 

매우 높은 유연성(실수 혹은 의도치 않는 코드 삽입 가능성 증가)

코드가 좀 복잡해짐

JSX 크기 증가

 

코드 예시)

import React, { useEffect, useState, Children } from 'react';
import styled from 'styled-components';

import { Decrement, Increment, Label, Reset } from './modules';

const StyledDiv = styled.div`
  display: inline-flex;
  flex-direction: row;
  border: 0.5px solid;
  gap: 0.5px;

  margin: 30px;
`;

function Counter({ children, onClick }) {
  const [counter, setCounter] = useState(0);
  const resetCounter = () => setCounter(0);

  return (
    <StyledDiv onClick={onClick}>
      {Children.map(children, (child) => {
        return React.cloneElement(child, {
          counter,
          resetCounter, // 그냥 첨가 가능하다는 예시용
          setCounter,
        });
      })}
    </StyledDiv>
  );
}

Counter.Reset = Reset;
Counter.Increment = Increment;
Counter.Decrement = Decrement;
Counter.Label = Label;

export default function AppEx() {
  return (
    <div>
      <Counter onClick={() => console.log('test1')}>
        <Counter.Increment />
        <Counter.Decrement />
        <Counter.Label />
      </Counter>

      <Counter onClick={() => console.log('test2')}>
        <Counter.Increment />
        <Counter.Label color="blue" />
        <Counter.Decrement />
      </Counter>

      <Counter onClick={() => console.log('test3')}>
        <Counter.Increment />
        <Counter.Label color="red" />
      </Counter>
    </div>
  );
}

 

구현하는 방식은 Context Api를 사용하는 방식과 Children와 cloneElement를 사용하는 방식 2가지를 발견했는데

 

ex) children & cloneElement 이용

function Counter({ children, onClick }) {
  const [counter, setCounter] = useState(0);
  const resetCounter = () => setCounter(0);

  return (
    <StyledDiv onClick={onClick}>
      {Children.map(children, (child) => {
        return React.cloneElement(child, {
          counter,
          resetCounter, // 그냥 첨가 가능하다는 예시용
          setCounter,
        });
      })}
    </StyledDiv>
  );
}

ex) context api 이용

const CounterContext = createContext(undefined);

function CounterProvider({ children, value }: any) {
  return <CounterContext.Provider value={value}>{children}</CounterContext.Provider>;
}

function useCounterContext() {
  const context = useContext(CounterContext);
  if (context === undefined) {
    throw new Error('useCounterContext must be used within a CounterProvider');
  }
  return context;
}

function Counter2({ children, onClick }) {
  const [counter, setCounter] = useState(0);
  const resetCounter = () => setCounter(0);

  const handleIncrement = () => {
    setCounter(counter + 1);
  };

  const handleDecrement = () => {
    setCounter(counter - 1);
  };

  return (
    <CounterProvider value={{ counter, handleIncrement, handleDecrement }}>
      <StyledDiv onClick={onClick}>{children}</StyledDiv>
    </CounterProvider>
  );
}

children & cloneElement 방식의 경우 cloneElement라길래 복사하는 비용이 크지 않을까? 검색해봤는데 

 

stackoverflow에 따르면 

어차피 JSX가 React.createElement(Object)로 전환되는 과정에서 cloneElement를 쓰면 똑같이 Object로 전환되면서 props만 전달해서 바꿔주는 식으로 작동해서 성능 이슈는 큰 문제가 아니라고 한다.

 

https://stackoverflow.com/questions/54922160/react-cloneelement-in-list-performance

 

React.cloneElement in List performance

I have doubts about React.cloneElement in List. Is that something that we should avoid doing or not, if we have lots of elements in list? Does React.cloneElement makes unnecessary re-renders that c...

stackoverflow.com

 

cloneElement 방식의 경우 depth가 깊어지면 다루기 좀 힘들어질꺼 같지만 간편하고

Context API 방식은 boilerplate?를 까는게 번거롭긴 하지만 depth에 상관없이 사용 가능할꺼 같다.

 

headlessui 란 오픈소스는 context 방식을 사용한것으로 보인다.

 

그외 비슷한 패턴들

 

쓸만한게 있을까 빠르게 훑고 넘어가자

 

Control Props Pattern

 

import React, { useState } from "react";
import { Counter } from "./Counter";

function Usage() {
  const [count, setCount] = useState(0);

  const handleChangeCounter = (newCount) => {
    setCount(newCount);
  };
  return (
    <Counter value={count} onChange={handleChangeCounter}>
      <Counter.Decrement icon={"minus"} />
      <Counter.Label>Counter</Counter.Label>
      <Counter.Count max={10} />
      <Counter.Increment icon={"plus"} />
    </Counter>
  );
}

export { Usage };

Example

 

Github: https://github.com/alexis-regnaud/advanced-react-patterns/tree/main/src/patterns/control-props

 

컴포넌트를 제어 컴포넌트로 사용 

하나의 'single source of truth' 단일 상태 사용 -> base component에 custom logic과 상태 부여

 

장점 

직접적 제어권 부여

 

단점

(compound 패턴보다) 구현의 복잡성 -> state, function, component 제어가 필요

 

 

Custom Hook Pattern

import React from "react";
import { Counter } from "./Counter";
import { useCounter } from "./useCounter";

function Usage() {
  const { count, handleIncrement, handleDecrement } = useCounter(0);
  const MAX_COUNT = 10;

  const handleClickIncrement = () => {
    //Put your custom logic
    if (count < MAX_COUNT) {
      handleIncrement();
    }
  };

  return (
    <>
      <Counter value={count}>
        <Counter.Decrement
          icon={"minus"}
          onClick={handleDecrement}
          disabled={count === 0}
        />
        <Counter.Label>Counter</Counter.Label>
        <Counter.Count />
        <Counter.Increment
          icon={"plus"}
          onClick={handleClickIncrement}
          disabled={count === MAX_COUNT}
        />
      </Counter>
      <button onClick={handleClickIncrement} disabled={count === MAX_COUNT}>
        Custom increment btn 1
      </button>
    </>
  );
}

export { Usage }

Example

Github: https://github.com/alexis-regnaud/advanced-react-patterns/tree/main/src/patterns/custom-hooks

 

장점
제어의 역전 -> 메인 로직이 custom hook으로 전환

 

단점

 

로직과 렌더링UI의 분리 -> (남이 보기에) 가독성 하락

 

 

Props Getters Pattern

 

import React from "react";
import { Counter } from "./Counter";
import { useCounter } from "./useCounter";

const MAX_COUNT = 10;

function Usage() {
  const {
    count,
    getCounterProps,
    getIncrementProps,
    getDecrementProps
  } = useCounter({
    initial: 0,
    max: MAX_COUNT
  });

  const handleBtn1Clicked = () => {
    console.log("btn 1 clicked");
  };

  return (
    <>
      <Counter {...getCounterProps()}>
        <Counter.Decrement icon={"minus"} {...getDecrementProps()} />
        <Counter.Label>Counter</Counter.Label>
        <Counter.Count />
        <Counter.Increment icon={"plus"} {...getIncrementProps()} />
      </Counter>
      <button {...getIncrementProps({ onClick: handleBtn1Clicked })}>
        Custom increment btn 1
      </button>
      <button {...getIncrementProps({ disabled: count > MAX_COUNT - 2 })}>
        Custom increment btn 2
      </button>
    </>
  );
}

export { Usage };

 

장점

 

getter를 통한 쉬운 사용 및 통합

복잡성을 getter에 감춤으로써 복잡성을 숨김

 

단점

 

Lack of visibility ->  getter가 어떻게 구현되어 있는지 모르는 사람들에게는 가독성이 하락한다

  //props getter for 'Counter'
  const getCounterProps = ({ ...otherProps } = {}) => ({
    value: count,
    "aria-valuemax": max,
    "aria-valuemin": 0,
    "aria-valuenow": count,
    ...otherProps
  });

getter는 이런식으로 구성되어있는데 spread 연산자로 뿌려주는 식이다.

 

State reducer pattern

 

custom hook 패턴에 reducer를 조합한 형태 

import React from "react";
import { Counter } from "./Counter";
import { useCounter } from "./useCounter";

const MAX_COUNT = 10;
function Usage() {
  const reducer = (state, action) => {
    switch (action.type) {
      case "decrement":
        return {
          count: Math.max(0, state.count - 2) //The decrement delta was changed for 2 (Default is 1)
        };
      default:
        return useCounter.reducer(state, action);
    }
  };

  const { count, handleDecrement, handleIncrement } = useCounter(
    { initial: 0, max: 10 },
    reducer
  );

  return (
    <>
      <Counter value={count}>
        <Counter.Decrement icon={"minus"} onClick={handleDecrement} />
        <Counter.Label>Counter</Counter.Label>
        <Counter.Count />
        <Counter.Increment icon={"plus"} onClick={handleIncrement} />
      </Counter>
      <button onClick={handleIncrement} disabled={count === MAX_COUNT}>
        Custom increment btn 1
      </button>
    </>
  );
}

export { Usage };

Example

Github: https://github.com/alexis-regnaud/advanced-react-patterns/tree/main/src/patterns/state-reducer

 

가장 파워풀하고 가장 Lack of visibility한 패턴이지 싶다.

 

느낀점?

 

협업시 가독성 문제 때문에 느낌상 1 ~ 3번 패턴이 젤 무난하지 않을까 싶다.

그 외로는 공통으로 사용할 수 있는 로직을 가지고(추상화) UI만 갈아끼우는 식으로 사용 가능할꺼 같다

 

reference 

 

https://javascript.plainenglish.io/5-advanced-react-patterns-a6b7624267a6

 

5 Advanced React Patterns

An overview of 5 modern advanced React patterns, including integration codes, pros and cons, and concrete usage within public libraries.

javascript.plainenglish.io

 

반응형

'소프트웨어공학 > 디자인패턴' 카테고리의 다른 글

메모  (0) 2022.03.25
프론트엔드에서의 레포지토리 패턴?  (0) 2022.03.18
[행위] 책임 연쇄 패턴  (0) 2022.03.13
[행위] 전략 패턴 & 커맨드 패턴  (0) 2022.03.07
[행동] 중재자 패턴  (1) 2022.03.01
반응형

Gap

'내부의 children 요소'들이 일정한 간격으로 떨어져 위치할 수 있게 사용하는 요소

grid 혹은 flex에서 사용 가능하다.

 

margin과의 차이점 

 

-> gap 스타일 속성은 인접한 요소가 있을때만 Gap을 만든다

 

See the Pen Untitled by lodado (@lodado) on CodePen.

 

호환성

 

출처 : https://caniuse.com/?search=GAP

메이저 브라우저는 전부 지원하는거 같은데 앞으로 호환성이 더 좋아지면 편리하게 쓸 수 있을것으로 기대된다.

 

ref

 

https://webisfree.com/2020-12-05/[css]-%EC%8A%A4%ED%83%80%EC%9D%BC%EC%86%8D%EC%84%B1-gap%EC%9D%84-flex%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0 

 

[css] 스타일속성 gap을 flex에서 사용하기

CSS 스타일 속성 gap에 대하여 알아보려고 합니다.

webisfree.com

반응형

'Front-end > CSS' 카테고리의 다른 글

font-family 상속 시키기  (0) 2022.11.04
css 챌린지  (0) 2022.10.05
[CSS] box-sizing  (0) 2022.07.11
loading spinner  (2) 2022.02.13
CSS 애니메이션 성능 개선  (0) 2022.01.27
반응형

react 17은 큰 변화는 없고 점진적인 upgrade를 위한 단계라고 한다.

 

 

이벤트 위임의 변경점

 

기존에는 document에 이벤트 위임을 붙여 이벤트를 처리했다면

17부터는 root에 이벤트를 붙여서 처리

 

https://ko.reactjs.org/blog/2020/08/10/react-v17-rc.html#changes-to-event-delegation

ex) 

<button onClick={handleClick}>

 

 

위 코드같은경우엔 내부적으로 

 

const rootNode = document.getElementById('root');
ReactDOM.render(<App />, rootNode);

 

root에 이벤트 위임을 넣어 처리

기존에는 (예시로) 리엑트 내부 e.stopPropagation() 코드가 혼용되서 쓰여지고 있는 JQuery 이벤트를 prevent하는 일이 있었는데

이런일을 방지하게 변경

또한 React17에서 event propagation이 보다 regular dom에 가깝게 변경

 

 

브라우저 최적화 (잡다한 변경점)

 

1. onScroll이 네이티브에선 버블링되지 않는데 React onScroll은 버블링되서 이벤트 버블링 제거 

 

2.

onFocus = focusin

onBlur = focusout 이벤트 사용하도록 변경?

(focusin focusout은 버블링 발생) 

 

3. Capture phase events (e.g. onClickCapture) 가 이제 진짜 캡처 페이즈 리스너 사용 (이전엔 어케했누?)

 

이벤트 풀링 최적화 제거 (No Event Pooling)

 

“event pooling” optimization이 별 의미없어서 삭제

비동기적으로 이벤트 객체에 접근 불가능했던게 삭제됨

 

function handleChange(e) {
  setData(data => ({
    ...data,
    // This crashes in React 16 and earlier:
    text: e.target.value <- before v17 : null
  }));
}

 

난 2021 입문자라(react 17 이후 사용) event pooling이 무슨 역할이었는지 정확히는 모르겠다

SyntheticEvent 객체는 이벤트 핸들러가 호출된 후 초기화되기에, 비동기적으로 이벤트 객체에 접근할 수 없었던 것이 수정되었다고 한다.

 

아마 setData 실행시기와 e의 생명주기가 일치하지 않았던것(초기화되버려서)으로 추론된다.

 

Effect Cleanup Timing

useEffect(() => {
  // This is the effect itself.
  return () => {    // This is its cleanup.  };});

 

useEffect가 보다 효율적으로 변경 

 

기본 컨셉 : 

 

Most effects don’t need to delay screen updates, so React runs them asynchronously soon after the update has been reflected on the screen.

 

(For the rare cases where you need an effect to block paint, e.g. to measure and position a tooltip, prefer useLayoutEffect.)

 

그러나 보통은 unmounting 될때 cleanup function은 보통 동기적으로 실행되게 사용되어 왔다.

(similar to componentWillUnmount being synchronous in classes)

이것은 탭 변경과 같은 큰 페이지 변경시 속도 저하를 초래했다. 

 

그래서 React 17에서는 항상 cleanup function은 비동기적으로 실행되게 변경되었다.

 

(In React 17, the effect cleanup function always runs asynchronously — for example, if the component is unmounting, the cleanup runs after the screen has been updated.)

 

동기적 상황을 원하면 useLayoutEffect를 쓰시라

 

(you might want to rely on the synchronous execution, you can switch to useLayoutEffect instead)

 

추가적으로 cleanup function은 언제나 new Effect가 실행하기 전에 실행된다. 

useEffect(() => {
  const instance = someRef.current;
  instance.someSetupMethod();
  return () => {
    instance.someCleanupMethod();
  };
});

 

Consistent Errors for Returning Undefined

let Button = forwardRef(() => {
  // We forgot to write return, so this component returns undefined.
  // React 17 surfaces this as an error instead of ignoring it.
  <button />;
});

let Button = memo(() => {
  // We forgot to write return, so this component returns undefined.
  // React 17 surfaces this as an error instead of ignoring it.
  <button />;
});

return undefined하면 에러

(제대로 return 안하면 에러) 

 

만약 아무것도 return 하지 않는 것을 명시적으로 나타내고 싶다면 return null 사용

 

ref

https://han7096.medium.com/react-v17-release-candidate-톺아보기-6a4b091965c4

 

React v17 Release Candidate 톺아보기

변경사항과 유의할점을 React 공식 문서와, 개인적인 지식을 덧붙여 정리한 글

han7096.medium.com

https://reactjs.org/blog/2020/08/10/react-v17-rc.html

 

React v17.0 Release Candidate: No New Features – React Blog

Today, we are publishing the first Release Candidate for React 17. It has been two and a half years since the previous major release of React, which is a long time even by our standards! In this blog post, we will describe the role of this major release, w

reactjs.org

 

반응형

'Front-end > React' 카테고리의 다른 글

react-flow에 undo, redo 구현  (0) 2022.09.03
Suspense를 위한 wrapper 만들기  (0) 2022.07.28
React18(개인 공부 메모용)  (0) 2022.06.09
react TMI  (0) 2022.04.13
drag and drop으로 창 크기 조절  (0) 2022.03.18
반응형

notion link

https://silver-blue-23c.notion.site/React18-0d46d803f3be437dbe7f90348dbecd09

 

React18

React 18의 알파 버전이 출시

* 바로 막 쓰기엔 무리일듯

자동 배치(Automatic Batching)가 도입되어 배치가 개선

 

배치 : React가 더 나은 성능을 위해 여러 개의 state 업데이트를 하나의 리렌더링 (re-render)로 묶는 것을 의미)

React 18의 createRoot를 통해, 모든 업데이트들은 어디서 왔는가와 무관하게 자동으로 배칭되게 된다.

 

이 뜻은, 추가적으로 timeout, promise, native 이벤트 핸들러와 모든 여타 이벤트는 React에서 제공하는 이벤트와 동일하게 state 업데이트를 배칭할 수 있다. 이를 통해 우리는 렌더링을 최소화하고, 나아가 애플리케이션에서 더 나은 성능을 기대한다.

상태 업데이트에 배치가 적용되지 않았으면 하는 경우엔 새롭게 추가된ReactDOM.flushSync함수를 사용

 

useTransition

React 17 까지는 상태 업데이트를 긴급 혹은 전환으로 명시하는 방법 X

 

 모든 상태 업데이트는 긴급 업데이트 → setTimeout이나 throttle, debounce 등의 테크닉을 써서 긴급 업데이트 방해를 우회하는 것이 최선이였다

 

useTransition을 쓰면

일부 상태 업데이트를 긴급하지 않은 것 (not urgent)로 표시

이것으로 표시되지 않은 상태 업데이트는 긴급한 것으로 간주

긴급한 상태 업데이트 (input text 등)가 긴급하지 않은 상태 업데이트 (검색 결과 목록 렌더링)을 중단할 수 있다.

 

쓰는 이유 : 느린 렌더링 & 느린 네트워크

업데이트를 긴급한 것과 긴급하지 않은 것으로 나누어 개발자에게 렌더링 성능을 튜닝하는데 많은 자유를 주었다고 볼 수 있다.

 

useId

 

useId는 클라이언트와 서버간의 hydration의 mismatch를 피하면서 유니크 아이디를 생성할 수 있는 새로운 훅이다. 이는 주로 고유한 id가 필요한 접근성 API와 사용되는 컴포넌트에 유용할 것으로 기대

 

useDeferredValue

 

useDeferredValue를 사용하면, 트리에서 급하지 않은 부분의 재렌더링을 지연

지연된 렌더링을 인터럽트하고 사용자 입력을 차단할때 사용

이는 debounce와 비슷하지만, 몇가지 더 장점이 있다.

지연된 렌더링은 인터럽트가 가능하며, 사용자 입력을 차단하지 않는다.

 

***** 아래는 Library author들에게 권장하는 hook들*****

(아직 어디에 쓰는진 잘..? library 제작자한테 추천한다고 한다 특히 useSyncExternalStore)

 

useSyncExternalStore

 

스토어에 대한 업데이트를 강제로 동기화 하여 외부 스토어가 concurrent read를 지원할 수 있도록 하는 새로운 훅

**useEffect**가 필요하지 않고, 이는 리액트 외부 상태와 통합되는 모든 라이브러리에 권장된다.

 

 

용어 설명 :

  • External Store: 외부 스토어라는 것은 우리가 subscribe하는 무언가를 의미한다. 예를 들어 리덕스 스토어, 글로벌 변수, dom 상태 등이 될 수 있다.
  • Internal Storeprops context useState useReducer 등 리액트가 관리하는 상태를 의미한다.
  • Tearing: 시각적인 비일치를 의미한다. 예를 들어, 하나의 상태에 대해 UI가 여러 상태로 보여지고 있는, (= 각 컴포넌트 별로 업데이트 속도가 달라서 발생하는) UI가 찢어진 상태를 의미한다.

**useExternalStore**는 리액트 18에서 스토어 내 데이터를 올바르게 가져올 수 있도록 도와준다.

 

useInsertionEffect

 

css-in-js 라이브러리가 렌더링 도중에 스타일을 삽입할 때 성능 문제를 해결할 수 있는 새로운 훅

 

The signature is identical to useEffect, but it fires synchronously before all DOM mutations.

 

리액트가 DOM을 변환한경우, 레이아웃에서 무언가를 읽기전 (**clientWidth**와 같이) 또는 페인트를 위해 브라우저에 값을 전달하기 전에 DOM에 대한 다른 변경과 동일한 타이밍에 작업을 하면 된다.

 

→ We must ensure to manipulate the CSS rules at the same time as other changes to the DOM. It can be when React mutates the DOM, before anything is read from the layout and before the content is visible in the browser.

useLayoutEffect 과 비슷,

hook is used to read the layout from the DOM and synchronously re-render.

 

순서 UseInsertionEffect → useLayoutEffect → useEffect

 

this hook does not have access to refs and cannot schedule updates.

 

선택적(Selective) Hydartion 등의 동시성(Concurrent) 기능이 추가

 

이 파트는 알아두면 좋을듯

 

 

새로운 서버 사이드 렌더링 아키텍처가 도입(<Suspense>와 React.lazy를 지원)

및 부분 SSR 지원

React 18에는 렌더링을 위한 3가지 API가 존재

  • renderToString: 유지 (제한된 Suspense 지원)
  • renderToNodeStream: Deprecated (Full Suspense를 지원하나, 스트리밍되지 않음)
  • pipeToNodeWritable: 신규 API, 사용 추천(스트리밍으로 Full Suspense) 지원

 

ref

 

https://medium.com/naver-place-dev/react-18을-준비하세요-8603c36ddb25

 

React 18을 준비하세요.

요약

medium.com

https://yceffort.kr/2022/04/react-18-changelog#starttransition-usetransition

 

Home

yceffort

yceffort.kr

 

반응형

'Front-end > React' 카테고리의 다른 글

Suspense를 위한 wrapper 만들기  (0) 2022.07.28
react 17(개인 공부용)  (1) 2022.06.09
react TMI  (0) 2022.04.13
drag and drop으로 창 크기 조절  (0) 2022.03.18
redux, redux-saga로 로딩, 에러 페이지 구현  (0) 2022.02.12
반응형

JSX(JavaScript Syntax Extension and occasionally referred as JavaScript XML)

 

const element = <h1>{title}</h1>;

- JSX은 HTML가 아니라 js이므로 camelCase 사용

 

- React는 별도의 파일에 마크업 & 로직을 넣어 인위적으로 분리 대신

둘다 포함하는 '컴포넌트'라는 단위로 관심사를 분리

 

- JSX는 주입 공격 방지(렌더링 하기 이전에 문자열로 변환되어 XSS 방지)

 

- Babel은 JSX를 React.createElement() 호출로 컴파일

 

DangerouslySetInnerHTML

function createMarkup() {
  return {__html: 'First &middot; Second'};
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />;
}

브라우저 DOM에서 innerHTML을 사용하기 위한 React의 대체 방법

* 사용은 하지만 innerHTML은 위험하다는 내용 상기

 

Rendered Element

 

- React Element들은 생성된 이후에 immutable

-> it represents the UI at a certain point in time.

 

State

 

- setState() state update는 비동기 처리 (State update May Be Asynchronous - React may batch multiple setState() calls into a single update for performance.)

 

- state Updates are merged

  constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []    
    };
  }

예를 들어 위와 같은 코드가 있을때

  componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments      });
    });
  }

 

위와 같은 코드를 실행하면 상태 변경 merge됨 (The merging is shallow, so this.setState({comments}) leaves this.state.posts intact, but completely replaces this.state.comments.)

 

- 데이터는 단방향(아래로 흐른다)

 

Event

 

- 이벤트는 합성 이벤트

function Form() {
  function handleSubmit(e) {
    e.preventDefault();    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

여기서 e는 리엑트 고유의 합성 이벤트(synthetic event)라 cross-browser 호환성을 걱정하지 않아도 된다

 

제어 컴포넌트 (Controlled Component)

<input>, <select> 등이 있을때 컴포넌트의 상태, props로 주어진 값을 활용하는 컴포넌트

ex) input 태그의 value 값을 useState로 제어)

 

비제어 컴포넌트

 

<input> 등이 자체적으로 상태를 갖는 경우 - (useRef등으로 관리)

해당 데이터와 UI의 동기가 이뤄지진 않으니 주의 (해당 상태가 변해도 컴포넌트의 상태가 변한게 아니므로 리렌더링이 일어나지 않는다)

 

ex) <input type="file"/> 의 경우 File API를 통해 js로 조작 가능한데 값이 읽기 전용이고 사용자만이 값 설정이 가능해서 비제어 컴포넌트

 

Key

 

가상돔 갱신할때 휴리스틱한 알고리즘으로 연산 속도를 돕는다

 

가정 : 

 

  • 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
  • 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해 줄 수 있다.

 

비교대상 - sibling

배열의 index를 key로 사용시 뒤죽박죽 되므로 변하지 않고 예상 가능한 '유일값' 사용

 

Hook

 

클래스 컴포넌트에서 함수 컴포넌트로 바꾼 동기 요약

1. 간결하고(simplify) 빠르게 

2. 빠르게(performance)

3. 재사용성(Reusing logic & avoid Giant components & Confusing classes)

 

그외 이유 

1. 기존 클래스 컴포넌트에서는 컴포넌트간 로직의 재사용이 힘들었는데 

hook을 쓰면 상태 관련 로직을 재사용하기 쉽게 만들어준다.

-> 생명주기 메서드 기반으로 쪼개는것보다 hook을 통해 서로 비슷한 일을 하는 함수 묶음으로 컴포넌트를 나눈다.

 

2. 클래스 기반은 사람과 기계를 혼동시킨다

자바스크립트의 class와 this는 사람을 혼동시킨다.

-> hook은 class 없이 사용하는 방법을 제시

 

hook 규칙 

 

react hooks API은 hooks임을 네이밍에서부터 드러내기 위해 use-* prefix를 사용

 

1. 오직 React 내에서만 hook 호출

2. 최상위에서만 호출 

 

훅은 전역 배열로 관리되고 생성되는 순서에 따라 컴포넌트를 key로 해 인덱스로 관리

-> 항상 최상위에서 호출되야한다 (호출 순서 흐름이 항상 예상 가능해야한다)

function Ex(){
    const [a, setA] = useState(0);
    const [b, setB] = useState(0);
 
}

정확한 비유는 아닐 수 있지만.. 위 같은 예시는 내부적으로

[a, setA, b, setB ...];

이런식으로 저장될텐데 if 분기문같은 이유로 인해 hook 호출 순서가 바뀌면 원치 않은 값을 사용할 가능성이 생김

 

useEffect의 Effect란?

 

sideEffect 할때 그 Effect!

데이터 가져오기, dom 수동 수정, dom 수정 등 이 모든게 side Effect

리엑트 상태(FSM)와 연관 없는 부분을 side Effect라 부르는듯?

 

useRef

 

일종의 자바스크립트 객체값(plain object)를 반환(참조값)하기 때문에

리엑트의 상태 & 렌더링 생명주기와 연관없이 고유의 값을 가진다

(useRef 바뀌어도 리렌더링 되지 않는다)

 

reference

 

https://reactjs.org/

 

React – A JavaScript library for building user interfaces

A JavaScript library for building user interfaces

reactjs.org

 

 

반응형

'Front-end > React' 카테고리의 다른 글

react 17(개인 공부용)  (1) 2022.06.09
React18(개인 공부 메모용)  (0) 2022.06.09
drag and drop으로 창 크기 조절  (0) 2022.03.18
redux, redux-saga로 로딩, 에러 페이지 구현  (0) 2022.02.12
redux 기본 구조  (0) 2022.02.02
반응형

가끔 공부하다보면 anycast란 내용이 보이길래 요약겸 정리해논다.

 

Anycast

Anycast는 각각 동일한 IP 주소가 할당된 엔드포인트 그룹에 여러 라우팅 경로를 제공하는 기술 - microsoft

 

??? 이렇게 말하면 무슨 말인지 감이 잡히지 않는다.

 

보통 우리가 알고 있는 IP는 '고유한' 주소이고, Unicast IP이다. 

우선 unicast가 뭔지 알고 넘어가야 될꺼 같다.

 

참고)

그림 출처 : https://microchipdeveloper.com/tcpip:tcp-vs-udp

유니캐스트 (Unicast) - 1 : 1 

유니캐스트는 정보를 전송하기 위한 프레임에 자신의 MAC 주소와 목적지의 MAC 주소를 첨부하여 전송

 

브로드캐스트 (Broadcast) 1 : N

브로드캐스트 방식은 로컬 네트워크에 연결되어 있는 모든 시스템에게 프레임을 보내는 방식

 

멀티캐스트(Multicast) 1: N (특정 그룹)

멀티캐스트는 네트워크에 연결되어 있는 시스템 중 일부에게만 정보를 전송하는 것으로 특정 그룹에 속해 있는 시스템에게만 한 번에 정보를 전송할 수 있는 방법

라우터가 멀티캐스트를 지원해야만 사용 가능하다는 단점

멀티캐스트 전송이 지원되면 송신자는 여러 수신자에게 한 번에 메시지가 전송되도록 하여

데이터의 중복 전송으로 인한 네트워크 자원 낭비를 최소화할 수 있게 된다.

멀티캐스트 전송을 위해서는 헤더에 수신자의 주소 대신 수신자들이 참여하고 있는 그룹 주소를 표시하여 패킷을 전송한다.

 

Anycast란?

 

Anycast IP는 서로 다른 호스트끼리 동일한 IP 주소를 가질 수 있는 개념이다.

 

링크 계층(L2)에서 맥 주소를 보고 데이터를 전달할때는 충돌이 일어나면 사용이 불가능하지만

라우터(L3)에서는 네트워크 라우팅 알고리즘(BGP)을 통해 가장 가까운곳으로 판단되는 쪽으로 사용 가능한 식으로 구현되어 있다. 

 

anycast는 주로 DNS 서비스에 많이 활용되고 있다는데 지역별로 DNS 서버를 분산하고, 항상 네트워크 경로상 가까운 DNS 서버가 응답하게 된다.

 

왜 이런 구조를 사용하냐면 root DNS에 하위 DNS 서버들이 계층적으로 쌓여있는 기존 구조에서는 네트워크 DNS DDos 공격이나 웜 공격등으로 root DNS가 마비되게 되면 전 세계 DNS가 마비되게 된다. 그래서 DNS를 적절히 분산 구성해 분산 처리 및 가까운 거리로 인한 네트워크 지연 감소 등 여러 이유로 사용하고 있다고 한다.

 

가장 유명한 예시로는 구글의 public DNS IP 8.8.8.8 이 anycast로 구성되어 있고,

전세계 국가에 분산되어 있다고 한다. 

 

장점

- L4/L7 로드밸런싱 장비 대신 쓰기 가능?(라우팅+서버)

- 사용자와 네트워크 적으로 가장 가까운 곳으로 안내

- L4/L7 이 대규모 트래픽 처리가 힘든데 서버로 바로 트래픽을 보내니 대규모 트래픽 처리에 용이

- 회선문제로 장애시 자동으로 다른곳으로 우회(회선 이중화 비용 절감)

- 오픈소스 -> 가격 X!

 

단점

- 네트워크 적으로 가장 가까운곳 !== 지리적으로 가까운곳

ISP 마다 라우팅 정책이 다르므로 제어가 힘들다.

- 라우터에서 라우팅만 하기 때문에 L4/L7에선 가능한? 서버의 상태 체크(죽었나 살았나)가 안된다는 단점

 

reference 

 

https://docs.microsoft.com/ko-kr/windows-server/networking/dns/deploy/anycast

 

Anycast DNS 개요

이 항목에서는 Anycast DNS에 대한 간략한 개요를 제공합니다.

docs.microsoft.com

 

https://tech.kakao.com/2014/05/29/anycast/

 

kakao의 Anycast 활용 사례

Overview 네트워크 기술 하나 중 Anycast 는 DNS 서비스에서 주로 사용하고 있지만 KAKAO는 Anycast 기술을 확장하여 여러가지 어플리케이션 서비스에 사용되고 있습니다. 특히 서버에서 Quagga 오픈소스를

tech.kakao.com

 

반응형

'CS > 네트워크' 카테고리의 다른 글

URL & URI & URN  (0) 2022.02.27
HTTP 메소드 멱등성, 안전한 메소드  (0) 2022.01.31
[TCP] 3-way handshake와 4-way handshake  (0) 2022.01.23
Pooling, Long Pooling, Streaming  (0) 2022.01.23

+ Recent posts