일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- shared lock
- querydsl
- 비관적락
- 즉시로딩
- JPQL
- fetch
- 일대다
- 지연로딩
- BOJ
- 동적sql
- 데코레이터
- 낙관적락
- PS
- 연결리스트
- 스프링 폼
- eager
- SQL프로그래밍
- 연관관계
- FetchType
- 다대다
- 스토어드 프로시저
- 이진탐색
- dfs
- CHECK OPTION
- execute
- 유니크제약조건
- 백트래킹
- exclusive lock
- 힙
- 다대일
- Today
- Total
흰 스타렉스에서 내가 내리지
변이를 사용하지 않고 배열 업데이트하기 본문
배열에 추가하기
push()는 배열을 변이시키므로 사용하면 안됩니다:
대신, 기존 아이템과 새 아이템을 포함한 새 배열을 생성합니다. 이를 위해 여러 가지 방법이 있지만, 가장 간단한 방법은 ... 배열 스프레드 구문을 사용하는 것입니다
import { useState } from 'react';
let nextId = 0;
export default function List() {
const [name, setName] = useState('');
const [artists, setArtists] = useState([]);
return (
<>
<h1>Inspiring sculptors:</h1>
<input
value={name}
onChange={e => setName(e.target.value)}
/>
<button onClick={() => {
setArtists([
...artists,
{ id: nextId++, name: name }
]);
}}>Add</button>
<ul>
{artists.map(artist => (
<li key={artist.id}>{artist.name}</li>
))}
</ul>
</>
);
}
배열에서 제거하기
배열에서 아이템을 제거하는 가장 쉬운 방법은 해당 아이템을 필터링하여 제외하는 것입니다.
즉, 해당 아이템을 포함하지 않은 새 배열을 생성합니다. 이를 위해 filter 메서드를 사용할 수 있습니다.
import { useState } from 'react';
let initialArtists = [
{ id: 0, name: 'Marta Colvin Andrade' },
{ id: 1, name: 'Lamidi Olonade Fakeye'},
{ id: 2, name: 'Louise Nevelson'},
];
export default function List() {
const [artists, setArtists] = useState(
initialArtists
);
return (
<>
<h1>Inspiring sculptors:</h1>
<ul>
{artists.map(artist => (
<li key={artist.id}>
{artist.name}{' '}
<button onClick={() => {
setArtists(
artists.filter(a =>
a.id !== artist.id
)
);
}}>
Delete
</button>
</li>
))}
</ul>
</>
);
}
배열 변형하기
배열의 일부 또는 모든 아이템을 변경하고자 할 때는 map()을 사용하여 새로운 배열을 생성할 수 있습니다.
map에 전달하는 함수는 데이터나 인덱스(또는 둘 모두)를 기반으로 각 아이템에 대해 수행할 작업을 결정할 수 있습니다.
import { useState } from 'react';
let initialShapes = [
{ id: 0, type: 'circle', x: 50, y: 100 },
{ id: 1, type: 'square', x: 150, y: 100 },
{ id: 2, type: 'circle', x: 250, y: 100 },
];
export default function ShapeEditor() {
const [shapes, setShapes] = useState(
initialShapes
);
function handleClick() {
const nextShapes = shapes.map(shape => {
if (shape.type === 'square') {
// No change
return shape;
} else {
// Return a new circle 50px below
return {
...shape,
y: shape.y + 50,
};
}
});
// Re-render with the new array
setShapes(nextShapes);
}
return (
<>
<button onClick={handleClick}>
Move circles down!
</button>
{shapes.map(shape => (
<div
key={shape.id}
style={{
background: 'purple',
position: 'absolute',
left: shape.x,
top: shape.y,
borderRadius:
shape.type === 'circle'
? '50%' : '',
width: 20,
height: 20,
}} />
))}
</>
);
}
배열에서 아이템 교체하기
일부 또는 모든 아이템을 교체하고자 하는 경우, 배열을 변이시키는 할당(arr[0] = 'bird')과 같은 방식은 사용해서는 안 됩니다.
대신 map을 사용하여 교체할 수 있습니다.
import { useState } from 'react';
let initialCounters = [
0, 0, 0
];
export default function CounterList() {
const [counters, setCounters] = useState(
initialCounters
);
function handleIncrementClick(index) {
const nextCounters = counters.map((c, i) => {
if (i === index) {
// Increment the clicked counter
return c + 1;
} else {
// The rest haven't changed
return c;
}
});
setCounters(nextCounters);
}
return (
<ul>
{counters.map((counter, i) => (
<li key={i}>
{counter}
<button onClick={() => {
handleIncrementClick(i);
}}>+1</button>
</li>
))}
</ul>
);
}
배열에 삽입하기
때로는 시작이나 끝이 아닌 특정 위치에 아이템을 삽입하고 싶을 수 있습니다.
이를 위해 ... 배열 스프레드 구문과 slice() 메서드를 함께 사용할 수 있습니다.
slice() 메서드는 배열을 "슬라이스"하여 자를 수 있습니다.
아이템을 삽입하기 위해, 삽입 지점 이전의 슬라이스, 그리고 새로운 아이템, 그리고 원래 배열의 나머지를 포함하는 배열을 생성합니다.
import { useState } from 'react';
let nextId = 3;
const initialArtists = [
{ id: 0, name: 'Marta Colvin Andrade' },
{ id: 1, name: 'Lamidi Olonade Fakeye'},
{ id: 2, name: 'Louise Nevelson'},
];
export default function List() {
const [name, setName] = useState('');
const [artists, setArtists] = useState(
initialArtists
);
function handleClick() {
const insertAt = 1; // Could be any index
const nextArtists = [
// Items before the insertion point:
...artists.slice(0, insertAt),
// New item:
{ id: nextId++, name: name },
// Items after the insertion point:
...artists.slice(insertAt)
];
setArtists(nextArtists);
setName('');
}
return (
<>
<h1>Inspiring sculptors:</h1>
<input
value={name}
onChange={e => setName(e.target.value)}
/>
<button onClick={handleClick}>
Insert
</button>
<ul>
{artists.map(artist => (
<li key={artist.id}>{artist.name}</li>
))}
</ul>
</>
);
}
Immer를 사용하여 간결한 업데이트 로직 작성하기
import { useState } from 'react';
import { useImmer } from 'use-immer';
let nextId = 3;
const initialList = [
{ id: 0, title: 'Big Bellies', seen: false },
{ id: 1, title: 'Lunar Landscape', seen: false },
{ id: 2, title: 'Terracotta Army', seen: true },
];
export default function BucketList() {
const [myList, updateMyList] = useImmer(
initialList
);
const [yourList, updateYourList] = useImmer(
initialList
);
function handleToggleMyList(id, nextSeen) {
updateMyList(draft => {
const artwork = draft.find(a =>
a.id === id
);
artwork.seen = nextSeen;
});
}
function handleToggleYourList(artworkId, nextSeen) {
updateYourList(draft => {
const artwork = draft.find(a =>
a.id === artworkId
);
artwork.seen = nextSeen;
});
}
return (
<>
<h1>Art Bucket List</h1>
<h2>My list of art to see:</h2>
<ItemList
artworks={myList}
onToggle={handleToggleMyList} />
<h2>Your list of art to see:</h2>
<ItemList
artworks={yourList}
onToggle={handleToggleYourList} />
</>
);
}
function ItemList({ artworks, onToggle }) {
return (
<ul>
{artworks.map(artwork => (
<li key={artwork.id}>
<label>
<input
type="checkbox"
checked={artwork.seen}
onChange={e => {
onToggle(
artwork.id,
e.target.checked
);
}}
/>
{artwork.title}
</label>
</li>
))}
</ul>
);
}
이는 원래 상태를 변이시키지 않고, Immer가 제공하는 특수 draft 객체를 변이합니다. 마찬가지로 draft의 내용에 push()나 pop()과 같은 변이 메서드를 적용할 수도 있습니다.
내부적으로 Immer는 draft에 대한 변경 사항에 따라 항상 다음 상태를 새롭게 구성합니다. 이렇게 하면 상태 변이 없이 이벤트 핸들러를 매우 간결하게 유지할 수 있습니다.
'React' 카테고리의 다른 글
상태 로직을 리듀서로 추출하기 (0) | 2024.05.19 |
---|---|
Immer를 사용하여 간결한 업데이트 로직 작성하기 (0) | 2024.05.19 |
이벤트 핸들러 props 로 전달하기, 이벤트 전파, 이벤트 방지 (0) | 2024.05.19 |
이벤트에 응답하기 - 발생할 수 있는 버그 (0) | 2024.05.19 |
JSX 스프레드 구문을 사용하여 props 전달하기 (0) | 2024.05.18 |