43일차(3)/React(4) : filter 함수 / 자식 component 활용 예제
- 자식 component 연결하여 배열 불러오기
- 자식 component 에서 만든 버튼에 이벤트가 발생하면 부모 component 에서 함수 호출하기
App03_ex3
- 자식 component 활용하기
//App03_ex3.js
import FriendComponent from "./components/friendComponent";
import { Component } from "react";
class App extends Component{
render(){
let friends=["바나나", "딸기", "복숭아"];
return(
<div className="container">
<h1>자식 component 사용 예제</h1>
<FriendComponent friends={friends} />
</div>
);
}
}
export default App;
- React에서도 자식 component를 정의하고 불러다가 쓰기 가능!
- let =[] 만들어둔 배열 데이터를 자식 컴포넌트에 전달해서 UI를 구성해볼 예정
- src 안에 components 폴더 생성, friendComponent.js 생성
- export default 주의!
- 부모 component 으로부터 받은 props를 사용해서 새로운 배열을 만들어서 list에 출력하겠다는 것
- 이 component를 app (root) 에서 불러다가 사용한다!
- FriendComponent 를 인식하고 있다. import해준다.
- 자식 component에 friends라는 property명으로 위에 정의되어 있는 friend 배열을 전달한 것이다.
- App03은 root component (좌) / FriendComponent 는 자식 component (우)
- import해서 jsx 안에서 사용한다.
- 자식component 상속 → return에서 불러오기 → 자식 component 에 들어있는 list에서 출력한다.
- react에서도 재활용 가능한 conponent를 얼마든지 만들 수 있다.
- 만들어 놓고 import해서 여러번 사용 가능.
- 자식 component의 return에 있는 내용이 root의 jsx의 <friendcomponent./> 가 있는 위치에 들어간다.
- 자식 component 를 사용하면서 property를 전달할 수가 있다. 읽어와서 friends에 담은 것!
- 이건 전달했기 때문에 자식 컴포넌트에서 참조가 가능한 것이다.
- friends 배열이 자식 컴포넌트의 friends 상수에 전달된다. (분홍색 화살표)
- friends라는 이름으로 props 를 전달했기 때문에 이렇게 사용하는 것! (파란색 화살표)
- 결국 자식 컴포넌트의 friends 에 들어간다. (분홍색 표시)
- this.props.friends 이 위치에 참조되는 것이 저 {friends} 인 것 (초록색 화살표)
- 그러면 자식 컴포넌트에서 props을 받아서 map으로 새로운 배열을 얻어내서 UI 출력에 활용한다.
App03_ex3.js
- 삭제버튼으로 배열 아이템 삭제하기
//App03_ex3.js
import FriendComponent from "./components/friendComponent";
import { Component } from "react";
class App extends Component{
state={
friends:["바나나", "딸기", "복숭아"]
}
render(){
return(
<div className="container">
<h1>자식 component 사용 예제</h1>
<FriendComponent friends={this.state.friends} deleteClicked={(idx)=>{
console.log("["+idx+"] 인덱스의 아이템을 삭제합니다.");
//this.state.friend 배열에서 idx 인덱스를 제외한 새로운 배열을 얻어낸다.
let newArray=this.state.friends.filter((item, index)=>{
return index !== idx;
});
this.setState({friends:newArray});
}} />
</div>
);
}
}
export default App;
FriendComponent.js
- 배열에 삭제 버튼 추가
// component/friendComponent.js
import { Component } from "react";
class friendComponent extends Component{
render(){
//부모 component 에서 전달된 props
const friends=this.props.friends;
//배열에 저장된 아이템을 이용해서 jsx 배열을 얻어낸다.
const list=friends.map((item,index)=>{
return (
<li key={index}>
{item}
<button onClick={()=>{
//props 로 전달된 deleteClicked 라는 함수 호출하면서 인덱스 값 전달하기
this.props.deleteClicked(index);
}}>삭제</button>
</li>
);
});
return(
<ul>
{list}
</ul>
);
}
}
export default friendComponent;
- 자식 Component 에서 일어나는 이벤트는 어떻게처리하는가?
- 자식 Component 에 삭제버튼을 추가해서 해당버튼을 누르면 삭제되도록 실행
- 1→2→3→4 순서대로 진행된다.
- 버튼 클릭→onClick 함수 실행→deleteClicked 함수로 차례 돌아와서→root의 함수 실행
- 자식 컴포넌트의 버튼에 이벤트가 걸려있어 실행되면 → 이벤트 함수 안에 있는 것을 root에서 실행한다.
- UI에서 삭제버튼을 누르면 deleteClicked 함수가 호출된다.
- 그런데, 삭제하려면 저 배열이 state로 관리되어야 한다.
- state로 옮겨주고 this.state.friends 로 바꿔주어야한다.
- 그런데 어떤 버튼을 누르느냐에 따라 삭제되는 값이 다르다.
- 즉, 자식 component 에서 삭제할 인덱스 값을 전달을 해줘야 한다.
- 자식 component 에서 함께 함수를 호출하면서 <li key={index} > 로 인덱스값 전달
- 그럼 이제 부모 component (root) 에서 삭제하고,
새 배열을 얻어내서 setState에서 교체해주면 된다.
- filter() 안에는 함수가 들어간다.
- return에서 true를 리턴하면 해당 인덱스를 남기고, false를 리턴하면 인덱스를 삭제
- 같은지 아닌지 정확히 비교하는것은 === 3개로 표시한다.
- 다른지 정확히 비교하는 것은 !==
- 이 연산자들을 사용하면 null, undefined 까지 다 구분해 준다.
- 버튼을 누르면 삭제되고 새로운 배열이 나타난다.
* filter 함수 설명 : 링크
- > 가 있다는 것은 T/F 값이 나온다는 것
- 여기서 words와 result는 참조값이 같지 않다. (다른 배열이다)
- 새로운 배열이라는 것은 즉 새로운 참조값을 말한다.
- filter() 괄호 안의 값이 true인 아이템만 남는다.
- (item, index)로 입력해서 인덱스 값을 사용할 수도 있다.
- 인덱스 i의 값이 0인 것만 남기기
- 인덱스가 2가 아닌 item을 모두 반환하는 새로운 배열을 가져온다.
- 이 함수를 쓰지 않으려면 for문을 사용해야 한다. 하나하나 돌면서 값을 비교해야 함.
- 빨간박스 공간이 비어있고 다른 함수가 없는 경우
(return을 생략하고) 로직이 아닌 리턴할 값만 남길수도있다.(람다식) → 여기서는 ( index !== idx )
App03_ex3.js (최종)
- 배열에 수정버튼 추가하기
//App03_ex3.js
import FriendComponent from "./components/friendComponent";
import { Component } from "react";
class App extends Component{
state={
friends:["바나나", "딸기", "복숭아"]
}
render(){
return(
<div className="container">
<h1>자식 component 사용 예제</h1>
<FriendComponent friends={this.state.friends}
deleteClicked={this.deleteClicked}
updateClicked={this.updateClicked}/>
</div>
);
}
deleteClicked = (idx)=>{
console.log("["+idx+"] 인덱스의 아이템을 삭제합니다.");
//this.state.friend 배열에서 idx 인덱스를 제외한 새로운 배열을 얻어낸다.
let newArray=this.state.friends.filter((item, index)=>{
return index !== idx;
});
this.setState({friends:newArray});
}
updateClicked = (data)=>{
//data는 {index:xxx, newName:xxx} 모양의 object이다.
let newArray=this.state.friends.map((item, index)=>{
return data.index === index ? data.newName : item;
});
let newArray2=this.state.friends.map((item, index)=>{
if(data.index === index){
return data.newName
}else{
return item;
}
});
let newArray3=this.state.friends.map((item, index)=> data.index === index ? data.newName : item);
this.setState({
friends:newArray //newArray2, 3도 가능
});
};
}
export default App;
FriendComponent.js (최종)
// component/friendComponent.js
import { Component } from "react";
class friendComponent extends Component{
render(){
//부모 component 에서 전달된 props
const friends=this.props.friends;
//배열에 저장된 아이템을 이용해서 jsx 배열을 얻어낸다.
const list=friends.map((item,index)=>{
return (
<li key={index}>
{item}
<button onClick={()=>{
let newName=prompt(item+"의 새로운 이름을 입력하세요");
//props로 전달된 updateClicked 라는 함수를 호출하면서 수정할 인덱스, 새 이름 전달
if (newName != null) {
this.props.updateClicked({
index,
newName});
}
}}>수정</button>
<button onClick={()=>{
//props 로 전달된 deleteClicked 라는 함수 호출하면서 인덱스 값 전달하기
this.props.deleteClicked(index);
}}>삭제</button>
</li>
);
});
return(
<ul>
{list}
</ul>
);
}
}
export default friendComponent;
- prompt 에서 새로운 값을 입력받아서 배열의 값을 변경하려면,
→ 부모 컴포넌트에서 새 이름을 전달받을 준비를 해야 한다.
→ 자식 컴포넌트에서는 새로운 이름과 index를 전달해주어야 한다.
this.props.updateClicked(index, newName);
this.props.updateClicked({
index:index,
newName:newName
});
this.props.updateClicked({index, newName});
- 모두 같은 값을 전달하는 코드이다!
1) 인자 2개를 단순히 전달한 것
2) object {} 로 묶어서 전달한 것
3) object {} 로 묶어서 전달한 것. 단, 변수와 같은 방의 이름을 생략했다!
- 자식 컴포넌트에서 object 값을 전달한 것
- object로 받았기 때문에 . 점찍어서 사용할 수 있다.
let newArray=this.state.friends.map((item, index)=>{
return data.index === index ? data.newName : item;
});
- data.index가 index와 같으면 data.newName을 리턴하고,
아니면(같지 않으면) item을 리턴한다.
let newArray=this.state.friends.map((item, index)=>{
return data.index === index ? data.newName : item;
});
let newArray2=this.state.friends.map((item, index)=>{
if(data.index === index){
return data.newName
}else{
return item;
}
});
let newArray3=this.state.friends.map((item, index)=> data.index === index ? data.newName : item);
- newArray : 리턴값의 조건을 3항연산자로 쓴 것
- newArray2 :리턴값의 조건을 if~else문으로 쓴 것
- newArray3 : 3항연산자+람다식으로 쓴 것 (가장 짧고 간단하게 표현 가능!)
- 위와 같이 prompt에서 입력값을 받아서 값이 수정된다.
- react는 기본으로 폴더를 만들 때 init, commit까지 한 상태로 생성된다!
- React 폴더를 외부 저장소와 연결하여 깃허브에도 push 완료!
- 오늘 배운 배열의 새로운 함수들..
.map() : 함수를 호출하여 새 배열 얻어내기
.concat() :아이템을 추가하여 새 배열 얻어내기
.filter() : 특정 조건에 만족하지 않는 아이템을 삭제하고 (필터링된) 새 배열 얻어내기
* map() 함수 설명 : 링크
* concat() 함수 설명 : 링크
* filter() 함수 설명 : 링크
- 배열의 map, concat, filter, reduce 함수 잘 알아두기!
'국비교육(22-23)' 카테고리의 다른 글
44일차(2)/React(6) : jsx 객체 활용, setState 함수 실습 (0) | 2022.12.08 |
---|---|
44일차(1)/React(5) : React 저장소 clone하기 / React 코드 리뷰 (0) | 2022.12.08 |
43일차(2)/React(3) : map, concat 함수 / 이벤트 처리 예제 (0) | 2022.12.08 |
43일차(1)/React(2) : React App 생성, React 기초 (1) | 2022.12.07 |
42일차(3)/React(1) : Node.js 초기 세팅, 주요 개념 정리 (0) | 2022.12.06 |