728x90
반응형
1. 컴포넌트 key 설정
Warning: Each child in a list should have a unique "key" prop.
컴포넌트마다 고유한 키를 설정해줘야한다. 무시해도되는 오류지만 이후 코드가 복잡해질 경우 고려해야될 사항이다.
render(){
const result = this.state.personList.map(
(data)=>(<Person key={data.id}
id={data.id}
name={data.name}
age={data.age}
height={data.height}/>)
)
return(
<div id='app'>
<InputComp/>
{result}
</div>
)
}
- Person 컴포넌트에 key 키워드를 추가해주면 해결된다.(컴포넌트를 구분해주는 역할로 사용 됨)
2. Props, State 예제코드
2.1 주요 개념 정리
- Props(속성): 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달하는 방법.
- State(상태): 컴포넌트 자체에서 관리하는 데이터.
- 함수 전달: 부모 컴포넌트가 자식 컴포넌트에게 함수를 props로 전달하여, 자식 컴포넌트에서 부모 컴포넌트의 상태를 변경할 수 있게 함.
2.2 코드 설명 및 주석 추가
inputComp.js
addPersonInfo = () => {
alert('추가!');
// 비구조화 할당을 통해 this.state에서 id, name, age, height를 추출
const { id, name, age, height } = this.state;
// 추출한 값들로 새로운 person 객체 생성
const personObj = { id: id, name: name, age: age, height: height };
// props로 전달된 addPersonInfo 함수를 호출하여 생성된 person 객체를 부모 컴포넌트(App)로 전달
this.props.addPersonInfo(personObj);
}
App.js
import { Component } from 'react';
import './App.css';
import Person from './components/Person.js';
import InputComp from './components/inputComp.js';
class App extends Component {
constructor(props) {
super(props);
// 상태 초기화: personList 배열에 초기 데이터 설정
this.state = {
personList: [
{ id: 1, name: '이민호', age: 20, height: 180 },
{ id: 2, name: '정채연', age: 21, height: 170 },
{ id: 3, name: '송중기', age: 22, height: 176 }
]
};
}
// 새로운 person 객체를 추가하는 함수
// obj는 InputComp.js의 addPerson에서 props로 받은 personObj이다.
addPersonInfo = (obj) => {
alert('추가!(App)');
console.log(obj);
// 기존 personList에 새로운 객체를 추가한 배열을 생성(concat 함수)
const concatedList = this.state.personList.concat(obj);
// 새로운 배열로 상태 업데이트
this.setState({
personList: concatedList
}); // setState가 호출되면 render 메서드가 다시 호출됨
}
render() {
// personList를 순회하며 Person 컴포넌트를 생성
const result = this.state.personList.map(
(data) => (
<Person
key={data.id}
id={data.id}
name={data.name}
age={data.age}
height={data.height}
/>
)
);
return (
<div id='app'>
{/* InputComp에 addPersonInfo 함수를 props로 전달 */}
<InputComp addPersonInfo={this.addPersonInfo} />
{result}
</div>
);
}
}
export default App;
2.3 설명
- App 컴포넌트에서 함수 전달하기
<InputComp addPersonInfo={this.addPersonInfo} />
- InputComp 컴포넌트를 렌더링할 때, addPersonInfo 함수를 props로 전달합니다.
- InputComp에서 함수 사용하기
this.props.addPersonInfo(personObj);
- InputComp는 this.props.addPersonInfo를 호출하여 부모(App) 컴포넌트에 새로운 person 객체를 전달합니다.
- 함수명 동일성 여부
- 함수명을 동일하게 할 필요는 없습니다. 중요한 것은 함수가 props로 전달되었고, 자식 컴포넌트에서 그 함수가 호출된다는 것입니다. 함수명은 다르게 지어도 문제없습니다.
2.4 요약
- 부모 컴포넌트(App)가 자식 컴포넌트(InputComp)에게 함수를 props로 전달합니다.
- 자식 컴포넌트(InputComp)는 이 함수를 호출하여 부모 컴포넌트의 상태를 변경할 수 있습니다.
- 함수명은 동일할 필요가 없으며, props로 전달된 함수를 사용하기만 하면 됩니다.
- props가 자바에도 있어서 매개변수인줄알았는데 property의 약자로, '부모에게 받아온 데이터'이다.
3. React 애플리케이션에서 조건부 렌더링을 구현하는 7가지 방법
4. 코드 추가 부분
- Person 추가, 삭제, 수정(버튼까지만) 기능 추가
- Person.js : 삭제, 수정 버튼
- InputComp.js : Person 추가
//App.js 코드
import {Component} from 'react';
import './App.css';
import Person from './components/Person.js'
import InputComp from './components/inputComp.js';
class App extends Component{
constructor(props){
super(props)
this.state={
personList:[{id: 1, name:'이민호', age: 20, height: 180},
{id: 2, name:'정채연', age: 21, height: 170},
{id: 3, name:'송중기', age: 22, height: 176}]
}
}
// 새로운 person 객체를 추가하는 함수
addPersonInfo = (obj) => {
alert('추가!(App)');
console.log(obj);
// 기존 personList에 새로운 객체를 추가한 배열을 생성
const concatedList = this.state.personList.concat(obj);
// 새로운 배열로 상태 업데이트
this.setState({
personList: concatedList
}); // setState가 호출되면 render 메서드가 다시 호출됨
}
// 특정 id를 가진 person 객체를 삭제하는 함수
deletePersonInfo = (id) => {
alert('삭제!(App)');
alert('Person 컴포넌트에서 받은 삭제할 아이디: ' + id); // 1,2,3
// personList 배열에서 id가 일치하지 않는 객체들만 필터링하여 새로운 배열 생성
const filteredList = this.state.personList.filter((data) => (data.id !== id));
// 새로운 배열로 상태 업데이트
this.setState({
personList: filteredList
});
}
render(){
// personList를 순회하며 Person 컴포넌트를 생성
const result = this.state.personList.map(
(data)=>(<Person key={data.id}
id={data.id}
name={data.name}
age={data.age}
height={data.height}
deletePersonInfo={this.deletePersonInfo}/>)
)
return(
<div id='app'>
<InputComp addPersonInfo={this.addPersonInfo}/>
{result}
</div>
)
}
}
export default App;
- 부모(App) 컴포넌트가 자식(Person) 컴포넌트에게 deletePersonInfo 함수를 props로 전달합니다.
- 자식(Person) 컴포넌트는 이 함수를 호출하여 자신의 id를 부모에게 전달합니다.
- 부모(App) 컴포넌트는 전달받은 id를 이용해 상태를 업데이트하고, 해당 id를 가진 객체를 personList에서 제거합니다.
//InputComp.js 코드
import { Component } from 'react';
import '../css/InputComp.css'
class InputComp extends Component{
constructor(props){
super(props)
this.state={
id:'',
name:'',
age:'',
height:'',
}
}
addPersonInfo = () => {
alert('추가!');
// 비구조화 할당을 통해 this.state에서 id, name, age, height를 추출
const { id, name, age, height } = this.state;
// 추출한 값들로 새로운 person 객체 생성
const personObj = { id: id, name: name, age: age, height: height };
// props로 전달된 addPersonInfo 함수를 호출하여 생성된 person 객체를 부모 컴포넌트(App)로 전달
this.props.addPersonInfo(personObj);
}
idChange=(e)=>{
console.log(e.target.value)
this.setState({
id:e.target.value
})
}
nameChange=(e)=>{
console.log(e.target.value)
this.setState({
name:e.target.value
})
}
ageChange=(e)=>{
console.log(e.target.value)
this.setState({
age:e.target.value
})
}
heightChange=(e)=>{
console.log(e.target.value)
this.setState({
height:e.target.value
})
}
render(){
return(
<div id='input-comp'>
<input type='text' placeholder='아이디' onChange={this.idChange}/>
<input type='text' placeholder='이름' onChange={this.nameChange}/>
<input type='text' placeholder='나이' onChange={this.ageChange}/>
<input type='text' placeholder='키' onChange={this.heightChange}/>
<button onClick={this.addPersonInfo}>추가</button>
</div>
)
}
}
export default InputComp;
//Person.js 코드
import '../css/Person.css'
function Person(props){
// 삭제 버튼 클릭 시 호출되는 함수
const deletePersonInfo = () => {
alert('삭제!(Person)');
// props로 전달받은 deletePersonInfo 함수를 호출하면서 자신의 id를 인자로 전달
props.deletePersonInfo(props.id);
};
const updatePersonInfo=()=>{
alert('수정!(Person)')
}
return(
<div id='person'>
<div>
아이디: {props.id}
</div>
<div>
이름: {props.name}
</div>
<div>
나이: {props.age}
</div>
<div>
키: {props.height}
</div>
<div>
{/* 삭제 버튼에 onClick 이벤트로 deletePersonInfo 함수 연결 */}
<button onClick={deletePersonInfo}>삭제</button>
<button onClick={updatePersonInfo}>수정</button>
</div>
</div>
)
}
export default Person;
- 상위 컴포넌트 App.js에게 props로 deletePersonInfo를 보낸다. 매개변수엔 props.id 값을 보낸다.
/*Person.css 코드*/
#Person {
height: 100px;
width: 50px;
background-color: aquamarine;
margin: 10px;
}
#person>div {
height: 30px;
}
#person>div:nth-child(1) {
background-color: blueviolet;
}
#person>div:nth-child(2) {
background-color: chartreuse;
}
#person>div:nth-child(3) {
background-color: brown;
}
#person>div:nth-child(3) {
background-color: lightsteelblue;
}
#person>div:nth-child(3) {
background-color: lightpink;
}
4.1 deletePersonInfo 함수의 작동 설명
주요 개념
- 함수 전달: 부모 컴포넌트가 자식 컴포넌트에게 함수를 전달합니다.
- 함수 호출: 자식 컴포넌트가 전달받은 함수를 호출하여 부모 컴포넌트의 상태를 변경합니다.
코드 설명 및 주석 추가
Person.js
function Person(props) {
// 삭제 버튼 클릭 시 호출되는 함수
const deletePersonInfo = () => {
alert('삭제!(Person)');
// props로 전달받은 deletePersonInfo 함수를 호출하면서 자신의 id를 인자로 전달
props.deletePersonInfo(props.id);
};
return (
<div>
<h2>{props.name}</h2>
<p>Age: {props.age}</p>
<p>Height: {props.height}</p>
{/* 삭제 버튼에 onClick 이벤트로 deletePersonInfo 함수 연결 */}
<button onClick={deletePersonInfo}>삭제</button>
</div>
);
}
export default Person;
App.js
import { Component } from 'react';
import './App.css';
import Person from './components/Person.js';
import InputComp from './components/inputComp.js';
class App extends Component {
constructor(props) {
super(props);
// 초기 상태 설정: personList 배열에 초기 데이터 설정
this.state = {
personList: [
{ id: 1, name: '이민호', age: 20, height: 180 },
{ id: 2, name: '정채연', age: 21, height: 170 },
{ id: 3, name: '송중기', age: 22, height: 176 }
]
};
}
// 새로운 person 객체를 추가하는 함수
addPersonInfo = (obj) => {
alert('추가!(App)');
console.log(obj);
// 기존 personList에 새로운 객체를 추가한 배열을 생성
const concatedList = this.state.personList.concat(obj);
// 새로운 배열로 상태 업데이트
this.setState({
personList: concatedList
}); // setState가 호출되면 render 메서드가 다시 호출됨
}
// 특정 id를 가진 person 객체를 삭제하는 함수
deletePersonInfo = (id) => {
alert('삭제!(App)');
alert('Person 컴포넌트에서 받은 삭제할 아이디: ' + id); // 1,2,3
// personList 배열에서 id가 일치하지 않는 객체들만 필터링하여 새로운 배열 생성
const filteredList = this.state.personList.filter((data) => (data.id !== id));
// 새로운 배열로 상태 업데이트
this.setState({
personList: filteredList
});
}
render() {
// personList를 순회하며 Person 컴포넌트를 생성
const result = this.state.personList.map(
(data) => (
<Person
key={data.id}
id={data.id}
name={data.name}
age={data.age}
height={data.height}
deletePersonInfo={this.deletePersonInfo} // deletePersonInfo 함수를 props로 전달
/>
)
);
return (
<div id='app'>
{/* InputComp에 addPersonInfo 함수를 props로 전달 */}
<InputComp addPersonInfo={this.addPersonInfo} />
{result}
</div>
);
}
}
export default App;
상세 설명
- App 컴포넌트에서 함수 전달하기
- deletePersonInfo 함수를 Person 컴포넌트에 props로 전달합니다.
<Person
key={data.id}
id={data.id}
name={data.name}
age={data.age}
height={data.height}
deletePersonInfo={this.deletePersonInfo}
/>
- Person 컴포넌트에서 함수 사용하기
- Person 컴포넌트는 props로 전달받은 deletePersonInfo 함수를 사용하여 자신의 id를 부모 컴포넌트에게 전달합니다.
props.deletePersonInfo(props.id);
- App 컴포넌트에서 상태 업데이트
- deletePersonInfo 함수는 전달받은 id를 이용하여 personList 배열에서 해당 id를 가진 객체를 제거합니다.
const filteredList = this.state.personList.filter((data) => (data.id !== id));
this.setState({ personList: filteredList });
요약
- 부모(App) 컴포넌트가 자식(Person) 컴포넌트에게 deletePersonInfo 함수를 props로 전달합니다.
- 자식(Person) 컴포넌트는 이 함수를 호출하여 자신의 id를 부모에게 전달합니다.
- 부모(App) 컴포넌트는 전달받은 id를 이용해 상태를 업데이트하고, 해당 id를 가진 객체를 personList에서 제거합니다.
'Coding 공부 > React' 카테고리의 다른 글
[React] Router 예제 (0) | 2024.06.10 |
---|---|
[React] 리액트 설치 및 실행, js파일 및 css 파일 리액트 연결, Hook, 리스트 렌더링 (0) | 2024.05.20 |
댓글