
props, state, event 3개가 서로 상호작용하며 애플리케이션의 역동성을 만든다.
!목표!

WEB을 누르면 welcome 메시지가, 각 목차를 누르면 그에 해당하는 내용이 뜨도록 만들 것이다.
그래서 우리는 각 링크에 이벤트를 만들 것이다. 그 이벤트를 클릭하면 App 컴포넌트의 state가 바뀌고 그 바뀐 state가 Content 컴포넌트에 동적으로 전달되도록 하는 것이 목표!
코드 변경 전 전체 코드↓
state 설정하기
지금 보고 있는 페이지가 welcome 페이지인지 read(읽기) 페이지인지 구분하기 위해 mode를 추가한다. 그리고 mode가 welcome일 때 content 영역에 표시할 텍스트도 추가해준다.

리액트는 props의 값이나 state 값이 바뀌면 그러면 그 state를 가지고 있는 컴포넌트의 render함수가 다시 호출된다. render 함수가 다시 호출되면서 render 함수 하위에 있던 컴포넌트들의 render 함수도 전부 다시 호출된다. 즉, props나 state가 바뀌면 화면이 다시 만들어지는 것.
render 함수 설정하기
이제 mode 상태에 따라 다른 결과를 출력하기 위해 조건문을 추가한다.

이제 이 조건문을 원하는 목적에 맞게 채워보자!

_title과 _desc의 기본값은 null 없는 값이다.
그리고 mode의 값에 따라 _title과 _desc에 각각 값을 지정한다. 그리고 이 변수를 props로 전달한다.

이제 mode의 값이 변경되면 App 컴포넌트의 render함수가 호출되고, 하위에 있는 Subject, TOC, Content 컴포넌트의 render함수도 다시 호출돼서 페이지가 만들어지게 된다.
그럼 목차를 클릭하면 mode가 바뀌도록 설정해보자.
우리의 목표에 따르면 WEB을 눌렀을 때 (Subject 컴포넌트의 a태그) Subject 컴포넌트 바깥에 있는 App 컴포넌트의 state가 변경되어야 한다. 하지만 이 과정이 어렵기 때문에 일단 Subject 컴포넌트 만들어둔 것을 풀어서 App에 직접 입력해서 구현해볼 것이다.

이렇게 컴포넌트를 주석 처리하고 안에 있던 내용을 직접 입력해두었다.
이제 할 것은 a 태그를 클릭했을 때 이벤트가 발생되는 것. JS를 사용한다면 onclick을 쓰면 되지만! 우리는 지금 리액트의 유사 html을 사용하는 것이다. 그러니 리액트의 규칙을 따라야 함! 리액트에서는 onClick을 사용.
<header>
<h1><a href='/' onClick={function(){
alert('hi');
}}>{this.state.Subject.title}</a></h1>
{this.state.Subject.sub}
</header>
이렇게 클릭을 했을 때 alert이 실행되도록 코드를 작성하였다.
그러면?

WEB을 클릭했을 때 메시지 창이 정상적으로 뜬다. 하지만!! 확인 버튼을 누르면 페이지가 리로드 된다.
페이지가 리로드 될 필요가 없는데 리로드가 되는 것은 효율적이지 못하다. 따라서 이러한 기본 동작을 막아주어야 한다!
이벤트를 실행할 때 기본적으로 첫 번째 parameter로 이벤트에 대한 정보를 받게 된다.
그래서 우리는 이렇게 받은 이벤트 정보를 통해 이벤트를 핸들링할 수 있게 되는 것이다.
그 이벤트 정보에 속해있는 함수 중 preventDefault를 이용해서 이벤트의 기본 동작을 막을 수 있다.
<header>
<h1><a href='/' onClick={function(e){
e.preventDefault();
alert('hi');
}}>{this.state.Subject.title}</a></h1>
{this.state.Subject.sub}
</header>
이렇게 기본동작을 막아주면 이제 WEB을 클릭해도 페이지가 전환되지 않는 것을 알 수 있다.
이제 state와 이벤트를 연결해주자.
a 태그를 누르면 App 컴포넌트의 state의 mode값이 변경되면 되므로
this.state.mode = 'welcome';
이 값을 추가하면 되지 않을까?
.
.
.
하지만 오류가 난다! 이 코드에는 두 가지의 문제점이 있다.
첫 번째, a를 눌렀을 때 이벤트가 실행되는 함수 안에서는 this 값이 설정되지 않아 컴포넌트 자기 자신을 가리키지 않는다.
이럴 때 사용하는 것이 bind이다. 함수에서 this를 찾을 수 없을 때 그 함수가 끝난 바로 직후에. bind(this)를 추가해주면 this가 컴포넌트 자기 자신을 가리키게 된다.
두 번째, 이대로 코드를 작성하면 리액트에서는 state값이 바뀐 줄 모른다.
그래서 리액트의 가이드대로 setState 함수를 사용해서 변경해주어야 한다.
따라서
onClick={function(e){
e.preventDefault();
this.setState({
mode: 'welcome'
});
}.bind(this)
이렇게 수정해주면 코드가 정상적으로 작동한다.

bind
render함수 안에서 this 값은 그 render가 속해있는 컴포넌트 자체를 가리킨다.
하지만 위에서처럼 함수를 사용할 경우 this 값이 정의되지 않는 것! 이럴 때 this 값을 지정하기 위해 bind 함수를 사용한다.
bind 함수에 대해 살펴보자.
let obj = {name: 'egoing'};
function bindTest(){
console.log(this.name)
};
bindTest();
이런 코드가 있을 때 bindTest 함수 안의 this를 obj로 연결하고 싶다. 이때 그냥 bindTest만 실행하면 당연히 안된다!
이럴 때 사용하는 것이 bind이다.
bindTest.bind(obj);
이렇게 입력을 하면 bindTest 내부에 bind에 의해서 obj가 this로 주입된다. 즉, bind로 인해 this가 obj인 새로운 함수가 복제되는 것.
let bindTest2 = bindTest.bind(obj);
bindTest2();
이렇게 변수로 설정하면 this 값이 원하는 대로 나온다.
setState
this.state.mode = 'welcome';
왜 이렇게 state 값을 직접 변경하는 것이 안되고 setState 함수를 이용해야 하는 것일까?
constructor 안에서 state를 수정할 땐 그냥 바로 수정해도 된다. 하지만 constructor 외부에서 동적으로 state값을 수정할 땐 setState 함수를 이용해서 변경하고 싶은 값을 객체 형태로 주어야 한다. 왜냐하면 위에처럼 바꾸면 리액트가 state 값이 바뀐 줄 모르기 때문에 render함수가 다시 호출되지 않는다. 따라서 setState를 사용해야 한다.
직접 만든 컴포넌트에서 이벤트 생산자 되어보기
컴포넌트의 제작자, 생산자 입장에서 컴포넌트 안에서 사용자가 설치한 함수를 호출하여 이벤트가 발생될 수 있도록 할 것이다.
즉, a태그를 클릭했을 때 컴포넌트의 사용자가 설치한 함수를 호출하도록 해야 한다.
return (
<div className="App">
<Subject
title={this.state.Subject.title}
sub={this.state.Subject.sub}>
onChangePage = {function(){
}}
</Subject>
컴포넌트 내에 이벤트를 설정해둬서(onChangePage) 사용자가 설치한 함수(function(){})를 호출하여 이벤트가 실행될 수 있도록 하는 것이다!
이제 Subject 컴포넌트에서 이벤트를 설정해보면
//Subject.js
class Subject extends Component{
render(){
return (
<header>
<h1><a href='/' onClick={function(e){
e.preventDefault();
this.props.onChangePage();
}.bind(this)}>{this.props.title}</a></h1>
{this.props.sub}
</header>
);
}
}
a를 클릭했을 때 일단 페이지가 리로드 되는 것을 막기 위해 preventDefault 함수를 실행한다. 그리고 사용자가 App.js에서 설치한 함수를 실행하면 된다. 그 값을 props로 받아오는 것.
그래서 this.props.onChangePage()는
//App.js
<Subject
title={this.state.Subject.title}
sub={this.state.Subject.sub}
onChangePage = {function(){
alert('hi');
}.bind(this)}
>
</Subject>
여기서 onChagePage를 가리키고 이것이 함수이기 때문에 ()를 붙여주는 것
이제 코드를 정리해보면
//App.js
<Subject
title={this.state.Subject.title}
sub={this.state.Subject.sub}
onChangePage={ function() {
this.setState({mode:'welcome'});
}.bind(this) }
>
//Subject.js
class Subject extends Component{
render(){
return (
<header>
<h1><a href='/' onClick={function(e){
e.preventDefault();
this.props.onChangePage();
}.bind(this)}>{this.props.title}</a></h1>
{this.props.sub}
</header>
);
}
}
글목록을 누르면 해당하는 글이 뜨도록 하기
HTML, CSS, JavaScript 를 누르면 그에 맞는 글이 하단에 뜨도록 할 것이다. 위와 같은 이벤트 설정이 필요하고 state에서 적절한 글을 찾아 출력하는 작업 필요하다.
//App.js
<TOC onChangePage={function(){
this.setState({mode: 'read'});
}.bind(this)}
data={this.state.contents}
></TOC>
//TOC.js
class TOC extends Component {
render(){
let lists =[];
let data = this.props.data
let i=0;
while(i<data.length){
lists.push(
<li key={data[i].id}>
<a
href={"/content/"+data[i].id}
onClick={function(e){
e.preventDefault();
this.props.onChangePage();
}.bind(this)}
>{data[i].title}</a>
</li>);
i+=1;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
이벤트 설정에 대한 코드의 구성은 위에서 설명한 것과 같다.
이제 HTML을 누르면 HTML 내용이, CSS를 누르면 CSS 내용이, JavaScript를 누르면 JS 내용이 나오도록 하면 완성.
App에 state에다가 selected_content_id를 만들어서 선택된 content를 idfmf 그곳에다가 저장하고 selected_content_id와 contents의 id값이 일치하는 것을 하단에 표시하도록 할 것이다.
constructor(props){
super(props);
this.state = {
mode: 'read',
selected_content_id:2,
state에 selected_content_id를 지정한다. 기본값은 2
만약 render내의 조건문에서 mode가 read일 때 실행되는 부분이 우리가 바꿔야 할 부분이다. 그래서 for문을 이용해서 contents의 id 값과 selected_content_id 값을 비교하여 같은 값이면 그 값을 지정하고 반복문을 끝낸다. (filter를 이용해서도 할 수 있다.)
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){
let data = this.state.contents[i];
if(data.id === this.state.selected_content_id){
_title = data.title;
_desc = data.desc;
break;
}
i = i + 1;
}
}
이제 TOC에서 onChangePage가 발생했을 때 setState를 통해서 selected_content_id를 지정해주면 된다.
사용자가 지정한 함수를 실행하는 것은 TOC 내의 onClick 함수 부분이다. 따라서
this. props.onChangePage(); 에서 클릭된 목록의 id 값을 인자로 받으면 될 것이다.
1. 태그의 속성을 설정하여 이용하는 방법
class TOC extends Component {
render(){
let lists =[];
let data = this.props.data
let i=0;
while(i<data.length){
lists.push(
<li key={data[i].id}>
<a
href={"/content/"+data[i].id}
data-id={data[i].id}
onClick={function(e){
e.preventDefault();
this.props.onChangePage(e.target.dataset.id);
}.bind(this)}
>{data[i].title}</a>
</li>);
i+=1;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
클릭한 data의 id 값을 받기 위해 a 태그의 속성으로 data-id를 주었다. 그래서 e.target.dataset.id를 통해 그 id 값을 받아와서 onChangePage의 인자로 주는 것이다.
//App.js
<TOC
onChangePage={function(id){
this.setState({
mode: 'read',
selected_content_id: Number(id)
});
}.bind(this)}
data={this.state.contents}
></TOC>
그러면 App 컴포넌트에서 그 아이디 값을 받아와서 selected_content_id로 지정하면 된다. 위에서 설정한 반복문을 통해 selected_content_id와 contents.id 값이 같은 경우 화면에 출력될 것이다. 여기서 contents.id 값은 숫자이고 selected_content_id은 문자열이기 때문에 Number를 이용해서 숫자로 바꿔주었다.
2. bind 이용하는 방법
속성을 이용하지 않고 bind를 이용하는 방법이 있다.
onClick={function(id, e){
e.preventDefault();
this.props.onChangePage(id);
}.bind(this, data[i].id)}
bind는 두 번째 인자의 값을 그 해당하는 함수의 첫 번째 매개변수로 전달한다.

목표 달성!
전체 코드↓
https://github.com/YJZero/React/tree/main/event%20%EC%84%A4%EC%A0%95
'개발 공부 > React' 카테고리의 다른 글
React #6 [update, delete] (0) | 2022.08.09 |
---|---|
React #5 [props와 state, create, push와 concat] (0) | 2022.07.16 |
React #3 [component 만들기,React Developer Tools, props, state, key] (0) | 2022.07.13 |
react#2 [샘플 어플리케이션 수정해서 코딩하기, 배포하기] (0) | 2022.07.13 |
react #1 [component 개념, 개발환경 구축하기] (0) | 2022.07.13 |

props, state, event 3개가 서로 상호작용하며 애플리케이션의 역동성을 만든다.
!목표!

WEB을 누르면 welcome 메시지가, 각 목차를 누르면 그에 해당하는 내용이 뜨도록 만들 것이다.
그래서 우리는 각 링크에 이벤트를 만들 것이다. 그 이벤트를 클릭하면 App 컴포넌트의 state가 바뀌고 그 바뀐 state가 Content 컴포넌트에 동적으로 전달되도록 하는 것이 목표!
코드 변경 전 전체 코드↓
state 설정하기
지금 보고 있는 페이지가 welcome 페이지인지 read(읽기) 페이지인지 구분하기 위해 mode를 추가한다. 그리고 mode가 welcome일 때 content 영역에 표시할 텍스트도 추가해준다.

리액트는 props의 값이나 state 값이 바뀌면 그러면 그 state를 가지고 있는 컴포넌트의 render함수가 다시 호출된다. render 함수가 다시 호출되면서 render 함수 하위에 있던 컴포넌트들의 render 함수도 전부 다시 호출된다. 즉, props나 state가 바뀌면 화면이 다시 만들어지는 것.
render 함수 설정하기
이제 mode 상태에 따라 다른 결과를 출력하기 위해 조건문을 추가한다.

이제 이 조건문을 원하는 목적에 맞게 채워보자!

_title과 _desc의 기본값은 null 없는 값이다.
그리고 mode의 값에 따라 _title과 _desc에 각각 값을 지정한다. 그리고 이 변수를 props로 전달한다.

이제 mode의 값이 변경되면 App 컴포넌트의 render함수가 호출되고, 하위에 있는 Subject, TOC, Content 컴포넌트의 render함수도 다시 호출돼서 페이지가 만들어지게 된다.
그럼 목차를 클릭하면 mode가 바뀌도록 설정해보자.
우리의 목표에 따르면 WEB을 눌렀을 때 (Subject 컴포넌트의 a태그) Subject 컴포넌트 바깥에 있는 App 컴포넌트의 state가 변경되어야 한다. 하지만 이 과정이 어렵기 때문에 일단 Subject 컴포넌트 만들어둔 것을 풀어서 App에 직접 입력해서 구현해볼 것이다.

이렇게 컴포넌트를 주석 처리하고 안에 있던 내용을 직접 입력해두었다.
이제 할 것은 a 태그를 클릭했을 때 이벤트가 발생되는 것. JS를 사용한다면 onclick을 쓰면 되지만! 우리는 지금 리액트의 유사 html을 사용하는 것이다. 그러니 리액트의 규칙을 따라야 함! 리액트에서는 onClick을 사용.
<header>
<h1><a href='/' onClick={function(){
alert('hi');
}}>{this.state.Subject.title}</a></h1>
{this.state.Subject.sub}
</header>
이렇게 클릭을 했을 때 alert이 실행되도록 코드를 작성하였다.
그러면?

WEB을 클릭했을 때 메시지 창이 정상적으로 뜬다. 하지만!! 확인 버튼을 누르면 페이지가 리로드 된다.
페이지가 리로드 될 필요가 없는데 리로드가 되는 것은 효율적이지 못하다. 따라서 이러한 기본 동작을 막아주어야 한다!
이벤트를 실행할 때 기본적으로 첫 번째 parameter로 이벤트에 대한 정보를 받게 된다.
그래서 우리는 이렇게 받은 이벤트 정보를 통해 이벤트를 핸들링할 수 있게 되는 것이다.
그 이벤트 정보에 속해있는 함수 중 preventDefault를 이용해서 이벤트의 기본 동작을 막을 수 있다.
<header>
<h1><a href='/' onClick={function(e){
e.preventDefault();
alert('hi');
}}>{this.state.Subject.title}</a></h1>
{this.state.Subject.sub}
</header>
이렇게 기본동작을 막아주면 이제 WEB을 클릭해도 페이지가 전환되지 않는 것을 알 수 있다.
이제 state와 이벤트를 연결해주자.
a 태그를 누르면 App 컴포넌트의 state의 mode값이 변경되면 되므로
this.state.mode = 'welcome';
이 값을 추가하면 되지 않을까?
.
.
.
하지만 오류가 난다! 이 코드에는 두 가지의 문제점이 있다.
첫 번째, a를 눌렀을 때 이벤트가 실행되는 함수 안에서는 this 값이 설정되지 않아 컴포넌트 자기 자신을 가리키지 않는다.
이럴 때 사용하는 것이 bind이다. 함수에서 this를 찾을 수 없을 때 그 함수가 끝난 바로 직후에. bind(this)를 추가해주면 this가 컴포넌트 자기 자신을 가리키게 된다.
두 번째, 이대로 코드를 작성하면 리액트에서는 state값이 바뀐 줄 모른다.
그래서 리액트의 가이드대로 setState 함수를 사용해서 변경해주어야 한다.
따라서
onClick={function(e){
e.preventDefault();
this.setState({
mode: 'welcome'
});
}.bind(this)
이렇게 수정해주면 코드가 정상적으로 작동한다.

bind
render함수 안에서 this 값은 그 render가 속해있는 컴포넌트 자체를 가리킨다.
하지만 위에서처럼 함수를 사용할 경우 this 값이 정의되지 않는 것! 이럴 때 this 값을 지정하기 위해 bind 함수를 사용한다.
bind 함수에 대해 살펴보자.
let obj = {name: 'egoing'};
function bindTest(){
console.log(this.name)
};
bindTest();
이런 코드가 있을 때 bindTest 함수 안의 this를 obj로 연결하고 싶다. 이때 그냥 bindTest만 실행하면 당연히 안된다!
이럴 때 사용하는 것이 bind이다.
bindTest.bind(obj);
이렇게 입력을 하면 bindTest 내부에 bind에 의해서 obj가 this로 주입된다. 즉, bind로 인해 this가 obj인 새로운 함수가 복제되는 것.
let bindTest2 = bindTest.bind(obj);
bindTest2();
이렇게 변수로 설정하면 this 값이 원하는 대로 나온다.
setState
this.state.mode = 'welcome';
왜 이렇게 state 값을 직접 변경하는 것이 안되고 setState 함수를 이용해야 하는 것일까?
constructor 안에서 state를 수정할 땐 그냥 바로 수정해도 된다. 하지만 constructor 외부에서 동적으로 state값을 수정할 땐 setState 함수를 이용해서 변경하고 싶은 값을 객체 형태로 주어야 한다. 왜냐하면 위에처럼 바꾸면 리액트가 state 값이 바뀐 줄 모르기 때문에 render함수가 다시 호출되지 않는다. 따라서 setState를 사용해야 한다.
직접 만든 컴포넌트에서 이벤트 생산자 되어보기
컴포넌트의 제작자, 생산자 입장에서 컴포넌트 안에서 사용자가 설치한 함수를 호출하여 이벤트가 발생될 수 있도록 할 것이다.
즉, a태그를 클릭했을 때 컴포넌트의 사용자가 설치한 함수를 호출하도록 해야 한다.
return (
<div className="App">
<Subject
title={this.state.Subject.title}
sub={this.state.Subject.sub}>
onChangePage = {function(){
}}
</Subject>
컴포넌트 내에 이벤트를 설정해둬서(onChangePage) 사용자가 설치한 함수(function(){})를 호출하여 이벤트가 실행될 수 있도록 하는 것이다!
이제 Subject 컴포넌트에서 이벤트를 설정해보면
//Subject.js
class Subject extends Component{
render(){
return (
<header>
<h1><a href='/' onClick={function(e){
e.preventDefault();
this.props.onChangePage();
}.bind(this)}>{this.props.title}</a></h1>
{this.props.sub}
</header>
);
}
}
a를 클릭했을 때 일단 페이지가 리로드 되는 것을 막기 위해 preventDefault 함수를 실행한다. 그리고 사용자가 App.js에서 설치한 함수를 실행하면 된다. 그 값을 props로 받아오는 것.
그래서 this.props.onChangePage()는
//App.js
<Subject
title={this.state.Subject.title}
sub={this.state.Subject.sub}
onChangePage = {function(){
alert('hi');
}.bind(this)}
>
</Subject>
여기서 onChagePage를 가리키고 이것이 함수이기 때문에 ()를 붙여주는 것
이제 코드를 정리해보면
//App.js
<Subject
title={this.state.Subject.title}
sub={this.state.Subject.sub}
onChangePage={ function() {
this.setState({mode:'welcome'});
}.bind(this) }
>
//Subject.js
class Subject extends Component{
render(){
return (
<header>
<h1><a href='/' onClick={function(e){
e.preventDefault();
this.props.onChangePage();
}.bind(this)}>{this.props.title}</a></h1>
{this.props.sub}
</header>
);
}
}
글목록을 누르면 해당하는 글이 뜨도록 하기
HTML, CSS, JavaScript 를 누르면 그에 맞는 글이 하단에 뜨도록 할 것이다. 위와 같은 이벤트 설정이 필요하고 state에서 적절한 글을 찾아 출력하는 작업 필요하다.
//App.js
<TOC onChangePage={function(){
this.setState({mode: 'read'});
}.bind(this)}
data={this.state.contents}
></TOC>
//TOC.js
class TOC extends Component {
render(){
let lists =[];
let data = this.props.data
let i=0;
while(i<data.length){
lists.push(
<li key={data[i].id}>
<a
href={"/content/"+data[i].id}
onClick={function(e){
e.preventDefault();
this.props.onChangePage();
}.bind(this)}
>{data[i].title}</a>
</li>);
i+=1;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
이벤트 설정에 대한 코드의 구성은 위에서 설명한 것과 같다.
이제 HTML을 누르면 HTML 내용이, CSS를 누르면 CSS 내용이, JavaScript를 누르면 JS 내용이 나오도록 하면 완성.
App에 state에다가 selected_content_id를 만들어서 선택된 content를 idfmf 그곳에다가 저장하고 selected_content_id와 contents의 id값이 일치하는 것을 하단에 표시하도록 할 것이다.
constructor(props){
super(props);
this.state = {
mode: 'read',
selected_content_id:2,
state에 selected_content_id를 지정한다. 기본값은 2
만약 render내의 조건문에서 mode가 read일 때 실행되는 부분이 우리가 바꿔야 할 부분이다. 그래서 for문을 이용해서 contents의 id 값과 selected_content_id 값을 비교하여 같은 값이면 그 값을 지정하고 반복문을 끝낸다. (filter를 이용해서도 할 수 있다.)
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){
let data = this.state.contents[i];
if(data.id === this.state.selected_content_id){
_title = data.title;
_desc = data.desc;
break;
}
i = i + 1;
}
}
이제 TOC에서 onChangePage가 발생했을 때 setState를 통해서 selected_content_id를 지정해주면 된다.
사용자가 지정한 함수를 실행하는 것은 TOC 내의 onClick 함수 부분이다. 따라서
this. props.onChangePage(); 에서 클릭된 목록의 id 값을 인자로 받으면 될 것이다.
1. 태그의 속성을 설정하여 이용하는 방법
class TOC extends Component {
render(){
let lists =[];
let data = this.props.data
let i=0;
while(i<data.length){
lists.push(
<li key={data[i].id}>
<a
href={"/content/"+data[i].id}
data-id={data[i].id}
onClick={function(e){
e.preventDefault();
this.props.onChangePage(e.target.dataset.id);
}.bind(this)}
>{data[i].title}</a>
</li>);
i+=1;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
클릭한 data의 id 값을 받기 위해 a 태그의 속성으로 data-id를 주었다. 그래서 e.target.dataset.id를 통해 그 id 값을 받아와서 onChangePage의 인자로 주는 것이다.
//App.js
<TOC
onChangePage={function(id){
this.setState({
mode: 'read',
selected_content_id: Number(id)
});
}.bind(this)}
data={this.state.contents}
></TOC>
그러면 App 컴포넌트에서 그 아이디 값을 받아와서 selected_content_id로 지정하면 된다. 위에서 설정한 반복문을 통해 selected_content_id와 contents.id 값이 같은 경우 화면에 출력될 것이다. 여기서 contents.id 값은 숫자이고 selected_content_id은 문자열이기 때문에 Number를 이용해서 숫자로 바꿔주었다.
2. bind 이용하는 방법
속성을 이용하지 않고 bind를 이용하는 방법이 있다.
onClick={function(id, e){
e.preventDefault();
this.props.onChangePage(id);
}.bind(this, data[i].id)}
bind는 두 번째 인자의 값을 그 해당하는 함수의 첫 번째 매개변수로 전달한다.

목표 달성!
전체 코드↓
https://github.com/YJZero/React/tree/main/event%20%EC%84%A4%EC%A0%95
'개발 공부 > React' 카테고리의 다른 글
React #6 [update, delete] (0) | 2022.08.09 |
---|---|
React #5 [props와 state, create, push와 concat] (0) | 2022.07.16 |
React #3 [component 만들기,React Developer Tools, props, state, key] (0) | 2022.07.13 |
react#2 [샘플 어플리케이션 수정해서 코딩하기, 배포하기] (0) | 2022.07.13 |
react #1 [component 개념, 개발환경 구축하기] (0) | 2022.07.13 |