🟢 리액트는 효율적으로 컴포넌트를 렌더링하고 관리하는 것이 중요 => 설계가 중요하다.
📢배열에서 key
👉🏻 리액트에서 배열(array)을 렌더링할 때, 각 항목에 고유한 key를 설정.
👉🏻 key는 배열이 업데이트, 삭제 또는 추가될 때 효율적인 렌더링을 가능하게 함. => key를 이용해 어떤 항목이 변경, 추가 또는 제거되었는지 빠르게 인식
users.map((u,i)=>(
<User user={u} key={i}/>
))
🟢 key가 없으면 리액트는 배열 항목의 변경 사항을 제대로 추적X => 성능 저하.
- 배열을 렌더링할 때는 항상 고유한 key를 지정
📢useRef()
👉🏻 useRef()로 컴포넌트 안의 변수 만들기
- 컴포넌트에서 특정 DOM을 선택할 때 사용
- 컴포넌트 안에서 조회, 수정을 할 수 있는 변수를 관리할 수 있음.
👉🏻 useRef()로 관리하는 변수는 값이 바뀐다고 하여 컴포넌트가 재렌더링 되지 않음
- useState보다 좀 더 효율적이다.
👉🏻 useRef()를 통해 관리하는 값들
- setTimeout / setInterval을 통해서 만들어지는 id
- 조회, 수정, 삭제 시 사용되는 id
- 외부 라이브러리를 사용하여 생성된 인스턴스
📢useRef() vs useState()
👉🏻 비슷하게 어떤 값을 저장하는 저장공간의 역할
👉🏻 컴포넌트 안에서 조회 및 수정할 수 있는 변수를 관리
👉🏻 useRef()로 관리하는 변수는 값이 바뀐다고 해도 컴포넌트가 재렌더링 되지 않음.
👉🏻 state : 변화 => 렌더링 => 컴포넌트 내부 변수들 초기화
👉🏻 ref : 변화 => 렌더링X => 내부 변수들 값 유지
=> 변경시 렌더링을 발생시키지 말아야 하는 값을 다룰 때 사용
=> 변화는 감지해야 하지만, 그 변화가 렌더링을 발생시키지 않아야 할 때 사용
📢실습
npx create-react-app list-app 명령어로 새로운 앱을 생성하여, 맛집 리스트 관리.
컴포넌트명 : Store.jsx / StoreList.jsx / CreateStore.jsx
App.js
import './App.css';
import StoreList from './components/StoreList';
function App() {
return (
<div className="App">
{/* 맛집 리스트 추가 두 개 정도만 미리 추가해 놓고, 추가할 수 있게 버튼 만들기. id, storeName, detail*/}
{/* 월미당(쌀국수집) */}
<StoreList />
</div>
);
}
export default App;
components/StoreList.jsx
import React, { useRef, useState } from 'react';
import CreateStore from './CreateStore';
import Store from './Store';
const StoreList = () => {
const nextId = useRef(3);
const [stores, setStore] = useState([
{
id: 1,
store: '월미당',
storeItem: '쌀국수'
},
{
id: 2,
store: '두리네',
storeItem: '베이글샌드위치'
}
]);
const [inputs, setInputs] = useState({
store: '',
storeItem: ''
})
const {store, storeItem} = inputs;
const onChange = (e) => {
const { name, value } = e.target;
setInputs({
...inputs,
[name]:value
})
}
const onCreate = ()=>{
//값이 추가되면....
//나중에 여기서 구현.
const storeD = {
id: nextId.current,
store,
storeItem
};
setStore(stores.concat(storeD));
setInputs({
store:'',
storeItem:''
})
nextId.current += 1;
}
const onRemove=(id) =>{
setStore(stores.filter(store => store.id !== id))
}
return (
<div className='storeList'>
<CreateStore
store={store}
storeItem={storeItem}
onChange={onChange}
onCreate={onCreate}
/>
{
stores.map(s=>(
<Store store={s} key={s.id} onRemove={onRemove} />
))
}
</div>
);
};
export default StoreList;
components/Store.jsx
import React from 'react';
const Store = ({ store, onRemove }) => {
// const store = props.store;
return (
<div className='store'>
<h3>
{store.store}({store.storeItem})
<button onClick={()=>onRemove(store.id)}>X</button>
</h3>
</div>
);
};
export default Store;
components/CreateStore.jsx
import React from 'react';
const CreateStore = ({ store, storeItem, onChange, onCreate }) => {
return (
<div className='createStore'>
<input
type="text"
name='store'
placeholder='가게명'
onChange={onChange}
value={store}
/>
<input
type="text"
name='storeItem'
placeholder='대표 메뉴'
onChange={onChange}
value={storeItem}
/>
<button onClick={onCreate}>create</button>
</div>
);
};
export default CreateStore;

'프론트엔드 > React' 카테고리의 다른 글
| Axios와 useEffect를 사용하여 데이터 가져오기 (0) | 2024.09.09 |
|---|---|
| TODO LIST 만들기 및 useMemo() 개념 (1) | 2024.09.09 |
| React 상태 관리, 라우팅 (0) | 2024.09.06 |
| React 기본 개념 및 컴포넌트와 라우팅 설정하기 (1) | 2024.09.06 |
| React 설치 및 서버 시작 실행, 개발자 도구 설치 (0) | 2024.09.04 |