List와 Key
List
리스트를 위해 사용되는 자료 구조 - 배열
배열을 사용해서 리스트 형태로 element을 렌더링할 수 있음
Key
리스트에 존재하는 아이템들을 구분하기 위한 고유한 문자열
여러개의 Component 렌더링 하기
map() 함수
배열에 들어 있는 각 변수에 어떤 처리를 한 뒤 렌더링하는 것
const doubled = numbers.map((number) => number * 2);
리액트에서 맵함수를 사용하여 앨리먼트를 렌더링하는 코드
const numbers = [1,2,3,4,5];
const listItems = numbers.map((number)=>
<li>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
- map함수를 사용해서 배열에 들어있는 숫자를 <li>태그로 감싸주고 있음
- 화면에 렌더링 하기 위해 ReactDOM.render 사용
기본적인 List Component
function NumberList(props){
const {numbers} = props;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return(
<ul>{listItems}</ul>
);
}
const numbers = [1,2,3,4,5];
ReactDOM.render(
<NumberList numbers={numbers}/>,
document.getElementById('root')
);
- props로 숫자가 들어있는 배열인 numbers를 받아서 목록으로 출력함
List의 Key
리액트에서의 key 값은 리스트에 있는 엘리먼트 사이에서만 고유한 값이면 됨.
key로 값을 사용하는 경우
const numbers = [1,2,3,4,5];
const listItems = numbers.map((number)=>
<li key={number.toString()}>
{number}
</li>
);
- numbers 배열의 숫자들이 중복되지 않는 경우는 정상적으로 작동
- 중복되면 key값이 중복돼서 고유해지지 않음.
key로 id를 사용하는 경우
const todoItems = todos.map((todo)=>
<li key={todo.id}>
{todo.text}
</li>
);
key로 index를 사용하는 경우
const todoItems = todos.map((todo, index) =>
//아이템들의 고유한 ID가 없을 경우에만 사용
<li key={index}>
{todo.text}
</li>
);
- map() 함수에서 두 번째 파라미터로 제공해주는 인덱스 값을 키값으로 사용
- 인덱스는 배열 내에서 현재 인덱스를 의미
- 배열에서 아이템의 순서가 바뀔 수 있는 경우 인덱스를 키값으로 사용 권장X
- 성능에 부정적 영향, 컴포넌트의 state와 관련하여 문제
- 리액트에서는 키를 명시적으로 넣지 않으면 index를 key값으로 사용
map() 함수 안에 있는 Elements는 꼭 key가 필요하다!
Form
사용자로부터 입력을 받기 위해 사용
Controlled Components
값이 리액트의 통제를 받는 Input Form Element

- HTML Form: 각 element가 자체적으로 state를 관리
- input, textarea, select가 각각 내부에 state를 가지고 있음
- Controlled Component: 모든 데이터를 state에서 관리
- react에서 모든 값을 통제할 수 있는 구조
- 사용자의 입력을 직접적으로 제어할 수 있다
예시 코드
function NameForm(props){
const [value, setValue] = useState('');
// 첫번째 파라미터 event: event 객체
//event.target: 현재 발생한 이벤트의 타겟, 여기서는 input element
const handleChange = (event) => {
setValue(event.target.value);
}
const handleSubmit = (event) => {
alert('입력한 이름: ' + value);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
이름:
<input type="text" value={value} onChange={handleChange}>
</label>
<button type="submit">제출</button>
</form>
)
}
- input태그의 value - 리액트 컴포넌트의 state에서 값을 가져다 넣어주는 것
- onChange에는 handleChange함수가 호출
- handleChange는 setValue함수를 사용하여 새롭게 변경된 값을 value라는 이름의 state에 저장
모든 입력값을 대문자로 변경
const handleChange = (event) =>{
setValue(event.target.value.toUpperCase());
}
- toUpperCase 함수를 사용하여 대문자로 변경한 뒤, 그 값을 state에 저장
다양한 Forms
Textarea 태그
- 여러 줄에 걸쳐 긴 텍스트를 입력받기 위한 HTML 태그
- textarea에 value라는 attribute를 사용하여 텍스트를 표시
<textarea value={value} onChange={handleChange} />
select 태그
- drop-down 목록을 보여주기 위한 html 태그
- select 태그에 value 사용
<select value={value} onChange={handleChange}/>
<option value="apple">사과</option>
...
</select>
//여러 개의 옵션 선택 가능: multiple attribute 사용
<select multiple={ture} value={['B', 'C']}>
file input 태그
디바이스의 저장 장치로부터 하나 또는 여러 개의 파일을 선택할 수 있게 해주는 HTML 태그
file input 태그는 값이 읽기 전용이어서 uncontrolled component
<input type="file"/>
여러 개의 입력을 받기 위해서는?
여러 개의 state를 선언하여 각각의 입력에 대해 사용
제어 컴포넌트에 value prop을 정해진 값으로 넣으면 코드를 수정하지 않는 한 입력 값을 바꿀 수 없음.
value prop을 넣되 자유입력할 수 있게 만들고 싶으면?
- 값에 undefined 또는 null
// 처음에는 입력 불가 상태
ReactDOM.render(<input value="hi" />, rootNode);
// 1초 뒤에 value가 null인 input 태그가 렌더링 -> 입력 가능한 상태
setTimeout(function() {
ReactDOM.render(<input vlaue={null}/>, rootNode);
}, 1000);
Lifting State Up
하나의 데이터를 여러 개의 컴포넌트에서 표현해야 하는 경우가 있음
- 각 컴포넌트의 state에서 데이터 각각 보관 X
- 가까운 공통된 부모 컴포넌트의 state를 공유해서 사용하는 것이 효율적
Shared State
어떤 컴포넌트의 state에 있는 데이터를 여러 개의 하위 컴포넌트에서 공통적으로 사용하는 경우
하위 컴포넌트가 공통된 부모 컴포넌트의 state를 공유하여 사용하는 것
'Develop > FE' 카테고리의 다른 글
| [React] fragments, forward props, 여러 JSX 슬롯 활용법 (1) | 2024.11.29 |
|---|---|
| [React] Context (1) | 2024.11.12 |
| [React] Handling Events & Conditional rendering (1) | 2024.10.03 |
| [React] Hooks (0) | 2024.09.27 |
| [React] State and Lifecycle (1) | 2024.09.19 |