React 이전에는 반복문으로 for문을 참 많이 사용했었습니다. 하지만 React로 넘어오니 for문을 사용하려면 임시 함수를 만들고, 그 함수를 실행해줘야 하더군요. 이런 번거로운 for문 대신 사용할 수 있는 다른 반복문이 없을까 하여 찾아보다가 React JSX에서는 Map과 Filter을 이용해서 반복문 처리를 해준다는 사실을 알게 됐습니다. 다행히도 Map과 Filter를 줄곧 알고리즘 문제 풀면서 익혀왔기 때문에 그다지 어렵지 않았습니다.
또, React에서는 기존 배열의 데이터를 유지하기 위해 새로운 배열을 생성해주는map()
과 filter()
을 사용합니다. push
대신 concat
을, splice
대신 slice
를 사용하는 이유도 이와 동일하지요.
💡불변성 유지가 왜 중요할까요?
리액트의 특징 중 하나가
Virtual DOM
으로 이벤트가 발생할 때마다Virtual DOM
을 생성하고 다시 그릴 때 기존 상태(State)와 이후 상태를 계속 비교하여 변경이 필요한 부분만 실제 DOM에 반영합니다. 이 덕분에 앱의 효율성과 속도가 많이 개선되었지요. 그러므로 리액트에서는 상태(State)를 업데이트할 때 기존 것은 건드리지 않고 업데이트 해줘야 리액트가 가진 장점을 살릴 수 있습니다.
{배열.map((element, index, array) => {
return <FunctionProps name={element.name} key={index} />;
}))}
export default function Alphabet() {
const [alphabet, setAlphabet] = useState(['b', 'a', 'n', 'a', 'n', 'a'])
alphabet.map((e, id, arr) => console.log(e, id, arr))
return(
<div className="Alphabet">
<ol>
{alphabet.map((e, id) =>
{ return <li key={id}>{e}</li>})}
</ol>
</div>
)
}
return은 반환할 값이 하나 일 때는 생략해도 가능합니다.
위의 예시에서 반환할 값이<li>
태그 하나이므로 생략해보겠습니다.<div className="Alphabet"> <ol> {alphabet.map((e, id) => (<li key={id}>{e}</li>))} </ol> </div>
export default function Alphabet() {
const [alphabet2, setAlphabet2] = useState([{id:1, alpha: "k"}, {id:2, alpha:"i"},{id:3, alpha:"w"},{id:4, alpha:"i"}])
return(
<div className="Alphabet">
<ol>
{alphabet2.map((alphabet) => {
return <li key={alphabet.id}>{alphabet.alpha}</li>
})}
</ol>
</div>
)
}
export default function Alphabet() {
const [alphabet2, setAlphabet2] = useState([{id:1, alpha: "k"}, {id:2, alpha:"i"},{id:3, alpha:"w"},{id:4, alpha:"i"}])
const [inputAlpha, setInputAlpha] = useState('');
const addAlpha = () => {
// setAlphabet2((prev) => {return {...prev, alpha: inputAlpha}})
const newAlpha = alphabet2.concat({
id: alphabet2.length + 1,
alpha: inputAlpha,
})
if(inputAlpha.trim().length === 0) return;
setAlphabet2(newAlpha);
setInputAlpha('');
}
return(
<div className="Alphabet">
<ol>
{alphabet2.map((e) => {
return <li key={e.id}>{e.alpha}</li>
})}
</ol>
<input type='text' placeholder='알파벳 입력' value={inputAlpha}
onChange={(e) => { setInputAlpha(e.target.value)}}
></input>
<button onClick={addAlpha}>Add</button>
</div>
)
}
const deleteAlpha = (id) => {
console.log(id);
const newAlpha = alphabet2.filter(alpha => {
return alpha.id !== id
})
setAlphabet2(newAlpha)
}
return(
<div className="Alphabet">
<ol>
{alphabet2.map((e) => {
return <li key={e.id}>{e.alpha}</li>
})}
</ol>
<hr />
<h1>doubleclick</h1>
{alphabet2.map((value) => {
//더블 클릭하면 deleteAlpha()함수 실행
return <li key={value.id} onDoubleClick={() => deleteAlpha(value.id)} >{value.alpha}</li>
})}
<input type='text' placeholder='알파벳 입력' value={inputAlpha}
onChange={(e) => {setInputAlpha(e.target.value);}}
></input>
<button onClick={addAlpha}>Add</button>
</div>
)