[stuff] state,constructor etc.

the Other Object·2023년 3월 8일
0
  • 성능 이슈 발생 = 느려진다

a태그와 Navigate

  • a태그 걸면 '새탭에서 링크열기'가능, 화면 전체가 새로고침 된다(href는 페이지 전체를 다시 그리기 때문에 재렌더링됨)
  • Link태그는 HTML5 History API를 사용해서 브라우저의 주소만 바꿀 뿐 페이지를 새로 불러오지는 않음
  • navigate는 변하는 값을 페이지이동
//html
<a href="#" />
//JSX
<Link to="#" />
  
* a태그는 href속성을 이용해서 경로를 생성하지만 link태그는 to속성으로 경로를 설정해준다.

//예제
import {Link} from 'react-router-dom';
<Link to="/about"> About </Link>

constructor, 상속과 super

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();

state개념

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)

* (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>
  )
}

0개의 댓글