리액트 공식문서 스터디 4일차(2)-접근성, 코드분할, Context

hyebin Jo·2022년 7월 22일
0

접근성

웹 접근성이란 어떠한 사용자(장애인, 노인 등), 어떠한 기술환경에서도 사용자가 전문적인 능력 없이 웹 사이트에서 제공하는 모든 정보에 접근할 수 있도록 보장하는 것.

📌시멘틱 HTML

시멘틱 태그란 의미에 맞게 태그를 작성하는 것을 말합니다. <div>와 같은 엘리먼트를 남발할때 HTML의 의미를 깨트리곤 합니다.
특히, 목록(<ol>, <ul>, <dl>)과 HTML <table>을 사용할 때 문제가 두드러집니다. 이 경우에는, React Fragment를 사용하여 여러 엘리먼트를 하나로 묶어주는 것을 권장합니다.

//예시
import React, { Fragment } from 'react';

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // 항목을 매핑할 때 Fragment는 반드시 `key` 프로퍼티가 있어야 합니다.
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

Fragmane 태그에 props가 필요없다면 짧게 줄여쓸 수 있습니다.

function ListItem({ item }) {
  return (
    <>
      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </>
  );
}

📌라벨링

<input><textarea> 같은 모든 HTML 폼 컨트롤은 구분할 수 있는 라벨이 필요합니다.

<label htmlFor="namedInput">Name:</label> //js에서 for 어트리뷰트는 JSX에서 htmlFor
<input id="namedInput" type="text" name="name"/>

📌포커스 컨트롤

✔ 키보드 포커스와 포커스 윤곽선

키보드 포커스는 키보드 입력을 받아들일 수 있는 DOM 내의 현재 엘리먼트를 나타냅니다.

✔ 원하는 콘텐츠로 건너뛸 수 있는 방법

사용자들의 키보드 탐색을 돕고 탐색 속도를 높일 수 있도록, 이전에 탐색한 영역을 건너뛸 방법을 제공해야 합니다.

  • Skip Navigation Links
// Skip Navigation Links 예시
<body>
<a href="#maincontent">Skip to main content</a>
...
<main id="maincontent">
<h1>Heading</h1>
<p>This is the first paragraph</p>
  • 의미있는 태그!
    사용자들이 원하는 섹션으로 빠르게 이동할 수 있도록, <main><aside> 같이 대표성을 띠는 랜드마크 엘리먼트와 역할들을 사용해 페이지 영역을 나누어야 합니다.

📌마우스와 포인터 이벤트

마우스 혹은 포인터 이벤트로 사용할 수 있는 기능을 키보드만으로도 사용할 수 있어야 합니다

코드 분할

유저가 처음 웹페이지에 접속하면 빌드된 파일을 웹페이지에 포함하여 보여주게 됩니다. 만약 앱이 커지면 파일의 크기도 커지고 로드 시간이 길어지게 됩니다.
이를 해결하기 위한 방법이 코드분할 입니다. 코드 분할은 앱을 “지연 로딩” 하게 도와주고 앱 사용자에게 획기적인 성능 향상을 하게 합니다.

📌import()

코드분할을 하는 가장 좋은 방법은 import()문법을 사용하는 방법입니다.

//before
import {alert} from './click';

function App() {
  const handleOnClick = () => alert();

  return <button onClick={handleOnClick}>클릭</button>;
}

//after
function App() {
  const handleOnClick = () => {
    import("./click").then((click) => { // 이렇게 import를 사용해 코드분할을 해줍니다.
      click.default();
    });
  };

  return <button onClick={handleOnClick}>클릭</button>;
}

📌React.lazy

React.lazy 함수를 사용하면 동적 import를 사용해서 컴포넌트를 렌더링 할 수 있습니다. React.lazy는 동적 import()를 호출하는 함수를 인자로 가집니다.

  • lazy 컴포넌트는 Suspense 컴포넌트 하위에서 렌더링되어야 하며, Suspense는 lazy 컴포넌트가 로드되길 기다리는 동안 로딩 화면과 같은 예비 컨텐츠를 보여줄 수 있게 해줍니다.
  • fallback prop은 컴포넌트가 로드될 때까지 기다리는 동안 렌더링하려는 React 엘리먼트를 받아들입니다.
import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}

📌Route-based code splitting

//라우트 기반 코드분할 예시
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);

⭐React.lazy는 현재 default exports만 지원합니다.

Context

context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.

❗❗ 여러 레벨에 걸쳐 props 넘기는 걸 대체하는 데에 context보다 컴포넌트 합성이 더 간단한 해결책일 수도 있습니다.

📌API

React.createContext

const MyContext = React.createContext(defaultValue);
defaultValue 매개변수는 트리 안에서 적절한 Provider를 찾지 못했을 때만 쓰이는 값입니다.

Context.Provider

<MyContext.Provider value={/* 어떤 값 */}>
Provider 하위에서 context를 구독하는 모든 컴포넌트는 Provider의 value prop가 바뀔 때마다 다시 렌더링 됩니다.

Class.contextType

class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    /* MyContext의 값을 이용한 코드 */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* ... */
  }
} //contextType 프로퍼티를 활용해 클래스 안에서 this.context를 이용해 해당 Context의 가장 가까운 Provider를 찾아 그 값을 읽을 수 있게됩니다. 

MyClass.contextType = MyContext;
//React.createContext()로 생성한 Context 객체를 원하는 클래스의 contextType 프로퍼티로 지정할 수 있습니다.

Context.Consumer

<MyContext.Consumer>
  {value => /* context 값을 이용한 렌더링 */}
</MyContext.Consumer>

Context.displayName

react 개발자도구에서 context를 어떻게 보여줄지 결정하는 문자열 속성

const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';

<MyContext.Provider> // "MyDisplayName.Provider" in DevTools
<MyContext.Consumer> // "MyDisplayName.Consumer" in DevTools

0개의 댓글