웹 접근성이란 어떠한 사용자(장애인, 노인 등), 어떠한 기술환경에서도 사용자가 전문적인 능력 없이 웹 사이트에서 제공하는 모든 정보에 접근할 수 있도록 보장하는 것.
시멘틱 태그란 의미에 맞게 태그를 작성하는 것을 말합니다. <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 예시
<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()
문법을 사용하는 방법입니다.
//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
함수를 사용하면 동적 import를 사용해서 컴포넌트를 렌더링 할 수 있습니다. React.lazy
는 동적 import()를 호출하는 함수를 인자로 가집니다.
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>
);
}
//라우트 기반 코드분할 예시
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를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.
❗❗ 여러 레벨에 걸쳐 props 넘기는 걸 대체하는 데에 context보다 컴포넌트 합성이 더 간단한 해결책일 수도 있습니다.
const MyContext = React.createContext(defaultValue);
defaultValue 매개변수는 트리 안에서 적절한 Provider를 찾지 못했을 때만 쓰이는 값입니다.
<MyContext.Provider value={/* 어떤 값 */}>
Provider 하위에서 context를 구독하는 모든 컴포넌트는 Provider의 value prop가 바뀔 때마다 다시 렌더링 됩니다.
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 프로퍼티로 지정할 수 있습니다.
<MyContext.Consumer>
{value => /* context 값을 이용한 렌더링 */}
</MyContext.Consumer>
react 개발자도구에서 context를 어떻게 보여줄지 결정하는 문자열 속성
const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';
<MyContext.Provider> // "MyDisplayName.Provider" in DevTools
<MyContext.Consumer> // "MyDisplayName.Consumer" in DevTools