1. State변경과 render함수
현재 상태는 위와 같다.
먼저 설계(?)를 해보자면,
-제일 위에 위치한 WEB에 링크를 달아서 링크가 눌리면 밑에 Content컴포넌트에 Welcome이라는 텍스트가 뜨게 할 것
-TOC에서 각 항목을 누르면 해당하는 내용을 Content컴포넌트에 보여줄 것
먼저 우선적으로 링크를 달 것이다.
Subject.js에서 먼저 <a>링크를 달아준다.
이 각 링크에 이벤트를 연결할 것이다.
링크를 누르면 App컴포넌트의 state가 바뀌고,
Content의 props값으로 전달되면서 동적으로 앱이 바뀌는 것을 만들어 볼 것이다.
다음으로 state를 세팅해보자.
현재 페이지가 welcome페이지인지 read페이지인지 구분하기 위해서 state에 mode라는 값을 둘 것이다.
mode가 welcome일 때는 Content 컴포넌트를 바꿀 것인데,
title은 welcome으로, desc는 Hello, React로 바꾸어보자.
리액트에서 state값이 바뀌면, 그 state를 가지고 있는 컴포넌트의 render 함수가 다시 호출된다.
render함수가 다시 호출되면서 하위에 있는 컴포넌트의 render도 모두 다 다시 호출된다.
render의 역할은 바로 어떤 html을 그릴 것인가 결정하는 것이라고 할 수 있다.
정리를 해보면,
리액트에서는 컴포넌트의 state값이나 props값이 바뀌면 render가 호출된다.
이 말은 즉, props나 state가 바뀌면 화면이 다시 그려진다는 의미이다.
mode의 값에 따라서 만들어지는 렌더링 결과가 달라지게 조건문을 사용해보겠다.
_title과 _desc라는 변수를 만들어주고,
mode가 welcome인 경우와 read인 경우로 나누어 작성해주었다.
달라지는 데이터들은 state에 있는 값들을 그대로 사용하였다.
왼쪽이 welcome일 때이고, 오른쪽이 read일때이다.
state값이 바뀌면 render가 호출된다고 말하였는데, 그것을 확인하기 위해 render함수 다음에 console.log를 찍어보았다.
왼쪽과 같이 console.log를 만들어주고 read로 mode가 변경되었을 때,
App 컴포넌트의 render가 호출될 때 뿐만 아니라, 하위 컴포넌트의 render 함수도 순서대로 호출된다는 것을 볼 수 있다.
지금까지는 직접 손으로 바꾸었지만, 링크를 누르면 바뀌는 것으로 바꿔보자.
2. Event 설치
먼저 가장 쉽게 구현해보기 위해,
subject에 있는 모든 내용을 풀어 App.js에 넣어 이벤트를 구현해볼 것이다.
다음과 같이 복사하여 붙여준다.
이제 여기서 직접 이벤트 프로그래밍을 하고, 끝난 다음에 header를 다시 subject로 패키징 할 것이다.
지금 하려고 하는 것은 링크를 클릭했을 때, 코드를 실행하는 것이다.
먼저 a태그에 onClick함수를 만들어주자.
1) preventDefault()
링크가 눌리면 원래는 href가 가르키는 주소로 이동하게 되어있는데 이 기본적인 동작을 막아야한다.
기본동작을 막기위해 preventDefault()를 적어준다. 여기서 e는 이벤트를 의미한다.
2) a태그 눌렸을 때, mode바꾸기
태그를 눌렀을 때, mode값을 welcome으로 바꾸려한다.
그럼 그냥 onclick안에 this.state.mode = 'welcome'이라고 쓰면 될까? 그렇지 않다.
현재는 이미 컴포넌트 생성이 끝난 후에 동적으로 state값을 바꾸는 것이기에,
this.~의 식으로 바꾸면 리액트입장에서는 우리가 몰래 바꾸는 것이 되므로, 렌더링을 할 수가 없게된다.
그러므로 바뀐 state가 적용되면서 다른 기능을 구현하기 위해서는 setState 함수로 바꾸어야한다.
3) bind(this)
함수 안의 this값이 컴포넌트 자기 자신을 가리키는게 아니라 아무것도 가리키고 있지 않으므로,
함수가 끝난 직후에 .bind(this)를 추가해주면 된다.
그러면 함수 안에서 this는 위 컴포넌트를 가리키게 된다.
3. 컴포넌트 Event 만들기
원래 header는 Subject.js 안에 있던 코드였지만, 이해를 위해 바깥쪽으로 코드를 뺐었다.
이제 바깥으로 뺀 코드를 다시 Subject안으로 넣어 활성화시켜보자.
만약 내가 원하는 이벤트를, 클릭되었을 때 실행되는 함수로 정하고 싶은데
그러면 저번처럼 props를 활용하면 된다.
내가 실행시키고 싶은 함수를 props로 전달해주면 되는 것이다.
저번에 props를 전달할 때 <Subject title={this.state.title}></Subject>라는 식의 전달 방식을 사용하였다.
이번에도 함수를 전달할 때,
props이름=전달값(지금은 전달해주고 싶은 함수)
라는 식으로 적으면 된다.
왼쪽의 코드처럼 App.js에서 Subject의 props로 onChange함수를 전달해준다.
onChangePage함수는 state를 바꾸게 하는 이벤트를 가진다.
Subject.js에서는 onClick 안에서 기본 동작을 막아준 뒤에,
props의 이름을 onChangePage로 설정해주어 함수를 불러준다.
실행 시에 state의 mode가 welcome으로 바뀌는 것을 확인할 수 있다.
TOC컴포넌트의 링크들이 눌렸을 때도 이벤트를 추가해주었다.
Subject때와 똑같이 해주되, mode를 'read'로 바꾸는 이벤트를 추가해주었다.
state의 mode가 read로 잘 바뀌는 것을 확인할 수 있다.
4. 컴포넌트 Event 만들기 (2)
이제 누르는 TOC 항목에 따라 다른 내용을 나오게 해보았다.
먼저 테스트로 기본적으로 2번째 항목인 CSS에 대한 내용이 보이게 한다고 해보았다.
selected_content_id=2를 해두고,
밑의 render함수 안의 내용을 변경해주었다.
만약 mode가 'read'이면,
i가 하나씩 증가하여 selected_content_id와 같아지면 보여주는 title과 desc를 변경해주었다.
그렇다면 누르는 컴포넌트에 따라 id를 다르게 전달하여,
원하는 내용을 보이게 하려면 어떻게 해야할까?
이 id를 넘겨주는 곳은 TOC.js 파일 안에 있는 onclick이라는 함수에서 onChangePage 함수를 호출하는 부분이다.
여기서 함수를 호출하면서 인자를 넘겨주면 된다.
여기서 e라는 이벤트 객체는 target라는 데이터를 가지고 있는데,
작업자 도구를 통해 확인해보면 target은 <a>를 가리키고 있다.
즉, e.target은 <a>를 가리키고 <a>안에 있는 데이터 중에 dataset이라는 것에 id가 들어있다.
그러므로 왼쪽에 보이는 것처럼
e.target.dataset.id로 id를 전달해주면 된다.
TOC.js파일 안의 <a>에서 onClick함수에서 onChangePage함수를 호출하면서 e.target.dataset.id를 전달한다.
전달한 id는 App.js에서 TOC에서 받는다.
받은 id를 selected_content_id에 저장해준다.
단 저장해줄 때, 위 코드처럼
selected_content_id:id
로 저장해주면, 이때의 id는 string이기에 숫자로 변환해주어야한다.
그러므로,
selected_content_id:Number(id)
로 저장해주어야한다.
[Reference]
생활코딩 React
'Web > React' 카테고리의 다른 글
10] React Update & Delete (0) | 2020.04.23 |
---|---|
9] React Create (0) | 2020.04.23 |
7] React State (0) | 2020.04.23 |
6.5] React Props (default props) (0) | 2020.02.29 |
6] React Component 분리 (0) | 2020.02.29 |