React

[REACT] React - 복습

Hwan'ss 2019. 8. 6. 17:34

2019.08.06(화) React - 복습

 

Ex01. 복습(props, state, event(button))

- 자식(자식 컴포넌트)에게 던지고 싶다면 props

- 자신이 사용할 것이라면 state(객체 형식이다), state는 setstate를 이용해서 값을 갱신해야 한다.

import React, { Component } from 'react';

class App extends Component {
  f1 = () => {
    console.log("App의 f1");
  }
  render() {
    return (
      <div>
        <h1>App</h1>
        <button onClick={this.f1}>App 버튼</button>

        {/* props 사용 */}
        <Bpp age={15}></Bpp>  
      </div>
    );
  }
}

class Bpp extends Component {
  state = {
    number : 20,
  }
  f2 = () => {
    console.log("Bpp의 f2");
  }
  render() {
    return (
      <div>
        <h2>Bpp</h2>
        <h3>{this.props.age}</h3>
        <h4>{this.state.number}</h4>
        <button onClick={this.f2}>Bpp 버튼</button>
      </div>
    );
  }
}

export default App;

Ex01 복습 실행결과

Ex02

- 부모가 가지고 있는 state, 함수, 필드를 자식이 쓸수가 있는가?

- 컴포넌트는 상속의 개념과는 좀 다르다.

- 자식이 사용하기 위해서는 부모가 props를 사용하여 던져주면 된다.

import React, { Component } from 'react';

class App extends Component {
  n1 = 10

  state = {
    n2 : 20,
  }

  f1 = () => {
    console.log("App f1()");
  }

  render() {
    return (
      <div>
        <h1>나는야 App</h1>
        {/* 가지고 있는 것을 넘기는 것은 무조건 { } 안에서 넣어서 넘긴다. */}
        {/* this.state를 넘겨도 되지만 this.state.n2로 n2 자체를 넘길 수 있다.*/}
        {/* this.state는 state 자체를 넘겨 가지고 있는 state 변수를 모두 사용 할 수 있다. */}
        <Bpp n1={this.n1} state={this.state} n3={this.f1}></Bpp>
      </div>
    );
  }
}

class Bpp extends Component {
  render() {
    return (
      <div>
        <h2>여기부터 Bpp 등장</h2>
        <h3>{this.props.n1}</h3>
        <h3>{this.props.state.n2}</h3>
        {/* 함수는 직접 호출은 불가능 하기 때문에 버튼을 이용해서 함수를 콜하도록 했다. */}
        <button onClick={this.props.n3}>Bpp btn</button>
      </div>
    );
  }
}

export default App;

Ex02 실행결과

Ex03

- App 컴포넌트에는 배열이 존재하는데 호랑이, 고양이, 앵무새가 들어있다.

- Bpp는 버튼을 가지고 있다.

- Bpp 버튼을 클릭하면 App의 배열 인덱스 값을 랜덤으로 받아와서 출력하도록 한다.

  • Ex03 -1(내가 작성)
import React, { Component } from 'react';

class App extends Component {
 
  arr = ["호랑이", "고양이", "앵무새"]

  rand = () => {
    console.log(this.arr[Math.floor(Math.random() * 3)]);
  }
  
  render() {
    return (
      <div>
        <h1>나는 App</h1>
        <Bpp rand={this.rand}></Bpp>
      </div>
    );
  }
}
class Bpp extends Component {
  render() {
    return (
      <div>
        <h2>두둥 Bpp 등장</h2>
        <button onClick={this.props.rand}>rand btn</button>
      </div>
    );
  }
}

export default App;

Ex03 -1 실행결과

  • Ex03 -2(강사님께서 작성)
import React, { Component } from 'react';

// 부모 컴포넌트 필드, 함수, 스테이트 사용
class App extends Component {
  state = {
    num:0
  }
  f1 = ()=>{ 
    //console.log('App f1 Call');
    this.setState({
      num:Math.floor(Math.random()*3)
    })
  }

  animal = ['호랑이', '코끼리', '독수리']
  render() {
    //console.log('render call 1');
    return (
      <div>
        <Bpp animal ={this.animal[this.state.num]} f1={this.f1}/>
      </div>
    );
  }
}

class Bpp extends Component {
  render() {
    //console.log('render call 2');
    console.log(this.props);
    return (
      <div>
        <button> {this.props.animal} </button>
        <button onClick={this.props.f1}>버튼1</button>
      </div>
    );
  }
}

export default App;

Ex03 -2 실행결과 1
Ex03 -2 실행결과2

Ex04

- React에서는 js문법과 클래스 문법을 모두 사용하기 때문에 문법 사용을 조심해야 한다.

- 새로 등장한 문법과 기존에 있던 문법의 차이를 이해해야 한다.

- => 에서는 바인딩을 자동으로 제공해 주지만 이전 함수 문법에서는 바인딩을 해서 사용해야 한다.

import React, { Component } from 'react';

class App extends Component {
  state = {
    num : 10,
  }

  // 생성자
  constructor() {
    super();
    // 이렇게 해야 사용가능 f2에서 console.log(this.state.num) 사용 가능
    // 이렇게 사용하기 귀찮아서 살찐 에로우에서 사용하면 자동으로 만들어준다(ES6 부터)
    // 그래서 살찐 에로우를 사용하는 것이 좋고 편리하다.
    this.f2 = this.f2.bind(this);  // ES5 까지의 문법
  }

  f1 = () => {
    console.log('App f1() call');
    console.log(this.state.num);
    
  }
  f2 = function() {
    console.log('App f2() call');
    // 이런 구조 함수에서 바인딩을 안하고 사용하면 에러가 발생한다.
    // 바인딩을 시켜주어야 사용을 할 수 있다.(ES6의 문법이다.)
    console.log(this.state.num);
  }

  a=10; // let을 붙이면 error가 난다.
  
  // render()는 함수인데 render()과 return 사이에 함수를 넣으면 안되는가?
  render() {
    let b=20; // let 반드시 붙여야 한다.(함수<js문법>안과 클래스 문법을 구별해야 한다.)
    
    function f3() {
      console.log('f3() call');
      
    }
    
    // 함수 내부에서는 살찐 에로우를 사용 할 수 없다.
    /*f3 = () => {
    }*/

    return (
      <div>
        <h1>App</h1>
        <button onClick={this.f1}>btn1</button>
        <button onClick={this.f2}>btn2</button>
        {/* this.f3을 호출하면 call 자체가 되지를 않는다. */}
        {/* 함수안의 함수이기 때문에 this를 사용하지 않아야 한다. */}
        <button onClick={f3}>btn3</button>
        <Bpp ></Bpp>
      </div>
    );
  }
}
class Bpp extends Component {
  render() {
    return (
      <div>
        <h2>Bpp</h2>
        
      </div>
    );
  }
}

export default App;

Ex04 실행결과

 

<알고가기>

- O-O-O-O-O-O 이렇게 컴포넌트들이 아래로 되어있다고 가정한다.

- 세 번째 컴포넌트의 연결을 끊게 되면 뒤의 컴포넌트가 다 깨지기 때문에 다시 상위 컴포넌트에 맞게 작성을 해야 한다.

- 위의 구조가 깨지지 않도록 전역변수를 사용하여 다른 컴포넌트들이 깨지지 않도록 하고 싶지만 React는 전역변수를 사용 할 수 없을 뿐더러 어떤 컴포넌트가 전역변수를 사용 하는지 모르는 상황이기 때문에 전역변수를 사용 할 수 없다.

- React에는 전역변수를 사용 할 수 있는 공간이 존재 하는데 이것을 리덕스라고 한다.

- 리덕스는 React의 꽃이다.

- 리덕스를 하기 위해서는 props, state를 반드시 알아야 리덕스를 공부하는데 문제가 발생하지 않는다.