[React] 불변성 유지와 반복문 렌더링 - Map, Concat, Filter (for, forEach, push X)

J.A.Y·2024년 3월 18일
0

javaScript

목록 보기
18/21
post-thumbnail

🔗배열 렌더링 React 공식 문서

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()

{배열.map((element, index, array) => {
	return <FunctionProps name={element.name} key={index} />;
}))}
  • 배열의 인자로 '요소'와 'index', 'array'가 넘겨지고, 이를 콜백함수로 실행해 새로운 배열을 만들어줍니다.
  • 이러한 점을 이용하여 반복문처럼 사용할 수 있습니다.
  • 여기서 'key'는 기존 요소와 새로운 요소를 비교할 때 사용됩니다. 따라서 다른 요소와 겹치지 않는 고유 값이어야 합니다.
  • 보통은 고유값을 부여하지만 없을 경우엔 index를 사용하기도 합니다. (단, index를 권장하진 않습니다.)

- Alphabet 1차 배열 순회하기

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>

1. Alphabet2 객체 배열 순회하기

  • 객체 배열은 구조분해로 작성해주면 됩니다.
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>
    )
}

Concat()

2. Alphabet2 객체 배열에 값 추가하기

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>
    )
}

Filter()

3. Alphabet2 객체 배열 값 삭제하기

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>
    )
profile
Done is better than perfect🏃‍♀️

0개의 댓글