//html
<a href="#" />
//JSX
<Link to="#" />
* a태그는 href속성을 이용해서 경로를 생성하지만 link태그는 to속성으로 경로를 설정해준다.
//예제
import {Link} from 'react-router-dom';
<Link to="/about"> About </Link>
1. class : javascript에서 class란, '생성자함수'를 의미한다.
- 함수(function)는 알고리즘 문제를 풀 때는 `특정 기능을 하는 구문을 묶을 때` 사용하는 문법이라면,
- 클래스(class)는 이렇게 만들어진 `함수와 변수들을 연관 있는 것끼리 묶을 때` 사용되는 문법이다.
- class 를 사용해서 묶어 놓는 이유는 '코드를 편하게 재사용하기 위해'서이다.
2. constructor : 생성자(constructor)는 객체를 만드는 역할을 하는 함수이다.
- 함수 내부의 생성자는 객체를 만들어 주기 위해 만드는 것이고
- '초기모델', '초기값'이라고 이해하면 된다.
- 즉, class 안의 constructor는 보통, 'class의 초기값을 설정해 주는데 사용'된다.
[예시코드]
class Lion {
// class의 초기값 설정, 생성자와 비슷하다고 보면 된다.
constructor(name) {
this.name = name
}
getName() {
console.log('my name is ' + this.name)
}
}
myLion = new Lion('King');
myLion.getName();
// 결과 : my name is King
3. 상속 : javascript에서 상속이란, 부모class의 속성을 그대로 물려받고 새로운 속성을 추가하여 확장할 수 있는 기능이다.
[2의 예시코드 + 상속]
class Animal {
constructor(leg) {
this.leg = leg
}
printAnimal() {
console.log(this.name + '은 다리가 ' + String(this.leg) + '개')
}
}
class Lion extends Animal {
// class의 초기값 설정, 생성자와 비슷
constructor(name) {
this.name = name
}
getName() {
console.log('my name is ' + this.name)
}
}
myLion = new Lion('King');
myLion.getName();
- 이런 식으로 부모 Class인 Animal을 만들어주고, Animal의 기능을 가져다 쓰기 위해 Lion 클래스에 extends 를 추가
4. Super
- 하지만, 위 코드를 실행하면 오류가 뜬다 → RefereneError: Must call super ~. 'super'가 꼭 필요하다는 오류가 뜸
- super 를 위 코드에 추가해보자,
[2의 예시코드 + 상속 + super]
class Animal {
constructor(leg) {
this.leg = leg
}
printAnimal() {
console.log(this.name + '은 다리가 ' + String(this.leg) + '개')
}
}
class Lion extends Animal {
constructor(name) {
// 이렇게 super class를 호출해준다.
super(name)
this.name = name
}
getName() {
console.log('my name is ' + this.name)
}
}
myLion = new Lion('King');
myLion.getName();
myLion.printAnimal();
// 결과 : my name is King
// King은 다리가 King개
[알게 된 점]
- Animal 이라는 부모 클래스(class)에서 자식 클래스(class)인 Lion의 this.name을 가져다 쓸 수 있다 라는 것
- super 는 부모 클래스의 constructor 의 input 이다 라는 것
👉🏻 사실상, 위의 최종 4번 코드예시는 결과는 잘 실행됐지만 올바르지 않은 예시이다, super를 올바르게 다시 사용해보면,
👉🏻
class Animal {
construtor(leg) {
this.leg
}
printAnimal() {
console.log(this.name + '은 다리가 ' + String(this.leg) + '개')
}
}
class Lion extends Animal {
constructor(name, leg) {
// 부모 constructor의 input으로 name, leg를 보내자
super(name, leg)
this.name = name
}
getName() {
console.log('my name is ' + this.name)
}
}
myLion = new Lion('King');
myLion.getName();
myLion.printAnimal();
1. State 란,
* 일반적으로 컴포넌트의 내부에서 변경가능한 데이터를 관리 해야 할 때에 사용한다.
* 프로퍼티(props)의 특징은 컴포넌트 내부에서 값을 바꿀 수 없다는 것이었는데,
* 값을 바꿔야 하는 경우도 분명히 존재하고 이럴 때는 state라는 것을 사용한다.
* 값을 저장하거나 변경할 수 있는 객체로 보통 이벤트와 함께 사용된다.
* 컴포넌트에서 동적인 값을 상태(state)라고 하며, 동적인 데이터를 다룰 때 사용된다고 볼 수 있다.
2. 어떤 상황에서 state를 사용하면 좋을지??
import React from 'react';
const Main = () => {
const myName = 'ikjoon';
const changeName = () => {
myName = myName === 'ikjoon' ? 'choiIkJoon' : 'itsFalse';
console.log(myName);
}
return (
<div>
<h1> 안녕하세요, {myName}입니다. </h1>
<button
onClick={changeName}
>
Change
</button>
</div>
);
};
export default Main;
// 하지만 이렇게 했을 때 버튼을 눌러도 재렌더링은 안되므로 react에서는 컴포넌트에서 동적인값을 상태State
// 라고 부르는 이 state 를 사용하여 변경하면 된다. useState를 사용하여 함수형컴포넌트에서 상태관리를 하는 방법 알아보기.
2-(1) 선언방법
* react 모듈에서 {useState} import 해주고 useState()를 선언해서 사용한다.
* useState의 변수값이 바뀌면 컴포넌트가 새롭게 렌더링된다.
* const [state, setState] = useState(initialState);
* const [데이터, 데이터변경함수] = useState(초기값:생략가능)
[useState를 사용한 코드]
import React from 'react';
const Main = () => {
const [myName, setMyName] = useState('ikjoon');
const changeName = () => {
setMyName(myName === 'ikjoon' ? 'choiIkJoon' : 'itsFalse');
}
return (
<div>
<h1> 안녕하세요, {myName}입니다. </h1>
<button
onClick={changeName}
>
Change
</button>
</div>
)
}
export defaule Main;
1. state는 함수 내에 선언 된 변수처럼 컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체
class Welcome extends React.Component {
constructor(props) {
super(props);
this.state = {name: 'mnms'} //2. Welcome이 이름이 포함 된 객체로 this.state를 초기화한다.
}
render() {
return (
// 3. React는 Welcome 컴포넌트의 render()메소드를 호출하고 이를 통해 React는 화면에 뭘 표시하면 되는지 알게 됨.
// (state의 name 값 호출하며 렌더)
<h1> hello, {this.state.name} </h1>
)
}
}
ReactDOM.render (
<Welcome />, //1.<Welcome />가 ReactDOM.render()로 전달 되었을 때 React는 Welcome컴포넌트의 constructor를 호출
document.getElementById('root') //4. Welcome의 렌더링을 위해 DOM을 업데이트한다.
);
// 결과 : hello, mnms
2. this.state.name = 'mnmzz'
- 이렇게 state 값을 직접 바꿀 수는 없음
- 반드시 setState()함수를 이용하여 state의 값을 바꿔야한다.
- setState()함수는 비동기적이고 여러개의 setState가 실질적으로 한번만 수행된다.
- 즉, setState()함수를 사용할 떄에는 prevState 에 세팅하는 것이 좋다
this.setState((prevState, props) => ({
// prevState의 값을 바꿔준다.
name: prevState.name = 'mnmzz'
}))
* (e) : '이벤트를 인자로 받는다'는 뜻
1.댓글 데이터 저장 : 댓글들의 데이터를 기록해야하므로 registComment라는 함수를 만든다
//state값에 댓글을 기록할 수 있는 comment키과 map을 돌려야했기 때문에
// 배열로 댓글들을 기록할 수 있는 replies 키를 줬다.
this.state = {
comment: '',
replies: []
}
// registComment()함수는 state의 comment 값을 input에 입력받는 값들로 변경해 주는 함수이다.
const registComment = (e) => {
// 데이터를 잘 받는지 확인하기 위해 console.log를 사용
console.log(this.state.comment);
this.setState({comment: e.target.value})
}
2. 댓글을 배열로 저장 및 input 초기화
//inputComment()함수를 만들어준다.
const inputComment = (e) => {
//push를 사용하기 위해 add변수를 만들었다, add는 replies값을 할당해줌
const add = this.state.replies;
//add.push를 통해서 replies값은 state의 comment값을 저장한다.
add.push(this.state.comment);
//this.setState로 인해 replies 값에 변경 된 replies 값을 받고 comment는 다음 댓글작성을 위해 초기화시킴
this.setState({replies: this.state.replies, comment:''});
console.log('최종리플: ' + this.state.replies);
}
3. 엔터 기능구현 및 댓글등록
// onKeyPress이벤트를 보면, key값을 객체로 가지고 있다.
const PressClick = (e) => {
console.log('clicked');
this.inputComment();
}
const PressEnter = (e) => {
// onkeyPress.key에서 enter값을 받았을 경우,
if (e.key === 'Enter') {
//inputComment 를 실행하게 했으며 위 코드에서(PressClick())
// 버튼을 클릭했을때도 함수가 실행되도록 함수를 만들었다.
this.inputComment();
}
}
4. ul에 li을 추가할 수 있도록 map을 사용했다.
<ul className='repliy'>
//.map(() => ()) 으로 작성해야 기능이 구현된다. (자바스크립트에서는 : .map(() => {}))
{this.state.replies.map((el) => (
<li> {el} </li>
))}
</ul>
1. 배열 메소드 map() : array메소드인 map함수를 사용하여 코드 반복을 실행할 수 있다.
const arr = ['배열요소1', '배열요소2', '배열요소3'];
arr.map((element, index) => {
console.log(element);
console.log(index);
});
*
** map은 배열 내장 메소드이기 때문에 '배열.map(콜백함수)' 형태로 작성하여 사용한다.
** map함수에 들어가는 '콜백함수'는 '첫번째 파라미터'로 배열의 요소가 순차적으로 들어가며
** '두번째 파라미터'는 현재 요소의 인덱스이다.
2. 리액트에서 map()함수 사용시 : 리액트에서 map함수는 자바스크립트 문법이므로 중괄호{} 안에 작성해사용가능
{
const arr = [2,22,20,0];
const newArr = arr.map((elements) => {
return elements*2;
});
console.log(newArr);
}
//결과 :: [4, 44, 40, 0]
* map()함수는 return값을 넣어주면 '새로운 배열을 반환'한다.
* 위 코드는 arr배열의 모든 요소에 2를 각각 곱한 값을 return
* 즉, 'newArr'배열을 arr배열의 각 요소*2가 된 값들이 '새로운 배열'로 만들어짐
3. 리액트에서 map함수로 html 반복하기
const App = () => {
// map()함수를 이용해 반복문을 돌릴 title 이라는 '배열[]'이다.
const title = ['titleNo1', 'titleNo2', 'titleNo3'];
return (
<div>
//title.map을 하면 title 배열의 길이(요소개수)만큼 반복하여 실행된다.
{title.map((titleElement, index) => {
return (
// div태그 안의 속성에 key값으로 준 index : 주지 않아도 렌더링은 되지만 콘솔창에서 에러메시지로 유니크키를 주라는 메시지 나타난다.
<div key={index}>
// 리턴값으로는 h2태그 안에 현재 반복문 실행 중인 배열의 요소를 바인딩하여 반환한다.
<h2>{titleElement}</h2>
</div>
);
})};
</div>
)
}