이번엔 상위 컴포넌트에서 정의한 메서드를 하위 컴포넌트에서 실행시켜보겠다.
메서드의 경우에도 props를 이용하여 전달받을 수 있다.
1) 상위 컴포넌트의 메서드 하위 컴포넌트에서 실행
상위 컴포넌트에서 hihihi를 alert하는 메서드를 만들고
이를 하위 컴포넌트에서 실행시키고자 한다.
App.js
/*----중략---*/
<Subject title = {this.state.subject.title} sub={this.state.subject.sub}
onChangePage={function(){
alert("hihihi");
}
.bind(this)
}/>
/*----중략---*/
Subject.js
/*----중략---*/
return (
<header>
<h1><a href='/'
onClick={function(e){
e.preventDefault();
//전달된 props에서 onChangePage() 실행
this.props.onChangePage();
}.bind(this)
}>{this.props.title}</a></h1>
{this.props.sub}
</header>
);
/*----중략---*/
App.js에서 onChangePage라는 function이 alert이 되도록 정의하고,
Subject.js에서 클릭 시 props를 이용하여 해당 메서드를 호출하였다.
결과
상단의 WEB 글자를 클릭하면, 상위 컴포넌트에서 선언한 onChangePage() 가 실행되어 alert이 출력되었다.
2) 하위 컴포넌트에서 상위 컴포넌트 내용 변경
이번에는 역으로 하위 컴포넌트를 이용하여 상위 컴포넌트의 내용을 변경하고자 한다.
내용을 변경하려면 state를 다시 세팅해야 함으로 위에서 선언한 메서드를 변경한다.
App.js
/*--- 중략 ---*/
<Subject title = {this.state.subject.title} sub={this.state.subject.sub}
onChangePage={function(){
if(this.state.mode === 'welcome'){
this.setState({mode:"read"}); //state는 바로 바꿀 수 없고, setter를 이용해야 함
}else{
this.setState({mode:"welcome"}); //state는 바로 바꿀 수 없고, setter를 이용해야 함
}
}
.bind(this)
}/>
/*--- 중략 ---*/
이제 클릭할 때 마다 mode가 변경되고,
mode의 변경을 인지하고 span의 내용이 변경된다.
![]() |
![]() |
WEB 을 클릭할 때 마다 아래 문구가 스위칭된다.
3) 문구 클릭 시, 해당 클릭 목록의 내용 가져오기
Toc.js
render(){
console.log("Toc render");
let lists=[];
const data = this.props.data;
let i = 0;
while(i<data.length){
lists.push(
<li key={data[i].id}>
<a data-id={data[i].id} href={"/content/"+data[i].id}
onClick={function(e){
debugger;
e.preventDefault();
this.props.onChangePage(e.target.dataset.id);
}.bind(this)}>
{data[i].title}
</a>
</li>
)
i++;
}
/*--- 중략 ---*/
a 요소에 data-id 속성을 주어 id를 추가하였다.
클릭 시 debugger가 작동하고, 이 후 props에 존재하는 onChangePage 함수를 호출한다.
이 때, 인자로 이벤트의 타겟(a요소)의 dataset의 id (data-id)를 사용한다.
App.js
- 생성자
constructor(props){
super(props);
this.state={
mode : 'read',
subject:{title:"WEB",sub:'World'},
selected_content_id : 2,
welcome:{title : "Welcome",desc:"Hello, React!"},
contents:[
{id:1, title : 'HTML', desc:'HTML is for infomation'},
{id:2, title : 'CSS', desc:'CSS is for design'},
{id:3, title : 'JavaScript', desc:'JavaScript is for interactive'}
]
}
}
App의 생성자에서는 selected_content_id를 추가하였다.
이를 통해 어떤 컨텐츠 숫자를 클릭했는지를 판단한다.
- render()의 return
return(
/*--- 중략 ---*/
<Subject title = {this.state.subject.title} sub={this.state.subject.sub}
onChangePage={function(){
this.setState({mode:"welcome"}); //state는 바로 바꿀 수 없고, setter를 이용해야 함
}
.bind(this)
}/>
<Toc data={this.state.contents} onChangePage={function(id){
this.setState({
mode:"read",
selected_content_id : Number(id)
}); //state는 바로 바꿀 수 없고, setter를 이용해야 함
}.bind(this)}/>
/*--- 중략 ---*/
return 하는 내용이다.
Subject 클릭 시에는 welcome 모드로,
Toc 클릭 시에는 read 모드로 전환한다.
Toc의 경우, id를 인자로 App.js에 전달해주고, selected_content_id를 숫자 형태의 id로 전환한다.
- render() 상단
render(){
console.log("App render");
let _title, _desc = null;
if(this.state.mode === 'welcome'){
_title = this.state.welcome.title;
_desc = this.state.welcome.desc;
} else if(this.state.mode === 'read'){
let i =0;
while(i<this.state.contents.length){
const data = this.state.contents[i]
if(data.id===this.state.selected_content_id){
_title = data.id;
_desc = data.desc;
break;
}
i++;
}
}
render 상위 부분이다.
state가 바뀔때마다 재랜더링된다.
mode에 따라 _title과 _desc의 값이 변하며
mode 가 read일 경우 selected_content_id와 같은 목록 id의 제목과 내용으로 변경한다.
결과
![]() |
![]() |
![]() |
![]() |
HTML 클릭 시 | CSS 클릭 시 | JavaScript 클릭 시 | WEB 클릭 시 |
'프론트엔드 > React' 카테고리의 다른 글
리액트 useState 여러 요소 다루기 (0) | 2022.05.06 |
---|---|
리액트 함수형 컴포넌트 (0) | 2022.05.05 |
리액트 기초 : Event(1) (0) | 2022.05.03 |
리액트 기초 : state (0) | 2022.05.02 |
리액트 기초 : Props (0) | 2022.05.01 |
댓글