Skip to content

State 와 Mobx

이경은,KyungEun Lee edited this page Jun 12, 2021 · 1 revision

1.react 의state 관리

2.mobx를 이용하여 state 관리

1.react의 state관리

1. faker 란?

가상의 이름 사진 이메일 등 정보등을 만들어 주는 프로그램 이다. 이것을 실행하기 위해서는 terminal에 아래와 같은 명령어를 사용한다.

npm i faker --save

더 알아 보기 위해서 아래 문서 참조

faker

2. setState를 활용해 state관리를 해보자!

⇒ 정보가 바뀔때 마다 그 정보를 render에 반영하기 위해서는 반드시 react의 state를 사용해야 한다.

  1. state를 사용해 현재 정보의 상태를 먼저 선언 해준다.
state  ={
    name:faker.name.findName(),
    avatar:faker.image.avatar(),
    emailfaker.internet.email(),
    };

2.generate가 클릭 될 때 마다 name ,avator,email의 정보가 바뀌고 이것을 setstate로 state를 바꿔준다.set state를 이용해서 date를 업데이트 해준다 만약에 하나의 정보만 바꾸고 싶으면 바꾸고 싶은 data만 setstate안에 넣어준다.

generate = () => {
//콘솔에 다른 정보들이 계속 찍히는 것을 볼 수있음
    console.log('faker.name.findName',faker.name.findName());
    console.log('faker.image.avatar',faker.image.avatar());
    console.log('faker.internet.email',faker.internet.email());
// 상태 변화에 따라 set
    this.setState((state)=>{
      return{
        name: faker.name.findName(),
      avatar: faker.image.avatar(),
      emailfaker.internet.email(),
      }
      
    });
}

예를 들어 아래 같이 넣어 주면 된다.

generate = () => {
// 상태 변화에 따라 set
    this.setState((state)=>{
      return{
        name: faker.name.findName(),
      }
      
    });

그럼 다음 과 같이 이름만 변경 된 화면을 볼 수있다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/da27d372-f80f-467b-b473-6a205a5b1ab4/Animation.gif

<주의!>

전체 코드.js

지금 페이커 말고도 다른 예제들도 들어 가있는 점 주의

import Link from 'next/link';
import faker from 'faker';
import React, { Component } from 'react';
import { render } from 'react-dom';
class About extends Component{
  state  ={
    
    name:faker.name.findName(),
    avatar:faker.image.avatar(),
    emailfaker.internet.email(),
    };
 //setstate를 이용해 정보를 갱신
  generate = () => {
    console.log('faker.name.findName',faker.name.findName());
    console.log('faker.image.avatar',faker.image.avatar());
    console.log('faker.internet.email',faker.internet.email());
    this.setState((state)=>{
      return{
        name: faker.name.findName(),
      avatar: faker.image.avatar(),
      emailfaker.internet.email(),
      }
      
    });
  }
  render(){
    return(
      <div>
        <h1>ABOUTFakerDemo </h1>
      <!--state안에 있는 정보들을 표현 해준다.그래서 this.state.name이렇게 작성한다-->
        <ol class="list-group list-group-numbered">
          <li class="list-group-item">
            <img src={this.state.avatar} alt=""/>
          </li>
          <li class="list-group-item">{this.state.name}</li>
          <li class="list-group-item">{this.state.email}</li>
        </ol>
        <li>
          <Link href = "/"><a>GO HOME</a></Link>
        </li>
        <a href = "/"> Go HOME (without link)</a>
                <!--generate 함수를 호출 하는 button-->
        <button onClick ={this.generate}>generate</button>
      </div>
    );
  }
}

export default About;

이것을 실행하면 아래 와 같이 상태들이 변화하는 것을 볼 수가 있다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/51f075bd-49d5-4d2e-b79a-c07b02fbedbc/Animation.gif

react의 state문서를 참고 해 보면 좋을 것 같다.

컴포넌트 State - React

<주의!>

비동기로 돌아가는 코드 이며

2. mobx를 이용하여 state 관리

위에서 처럼 setstate로 state를 관리 할 수있지만 이것의 단점은 하나의 변수에 여러개의 변수가 들어 있는 경우 각각의 변수 변경이 안된다.

이것이 무슨 말이냐면 name에는 fristname,lastname이 있는데 fristname만 뜨게 하고 싶다 하는 경우

아래 처럼 name만 변경 해주면 될 것 처럼 보인다.

import Link from 'next/link';
import faker from 'faker';
import React, { Component } from 'react';
import { render } from 'react-dom';
class About extends Component{
  state  ={
   
// name 부분 변경 됨
    name = {
    fristName:faker.name.firstName(),
    lastNmae: faker.name.lastName(),
  };
    avatar:faker.image.avatar(),
    emailfaker.internet.email(),
    };
 //setstate를 이용해 정보를 갱신
  generate = () => {
    console.log('faker.name.findName',faker.name.findName());
    console.log('faker.image.avatar',faker.image.avatar());
    console.log('faker.internet.email',faker.internet.email());
    this.setState((state)=>{
      return{
       *** name = fristName:faker.name.firstName(), // 이부분 변경***
      avatar: faker.image.avatar(),
      emailfaker.internet.email(),
      }
      
    });
  }
  render(){
    return(
      <div>
        <h1>ABOUTFakerDemo </h1>
      <!--state안에 있는 정보들을 표현 해준다.그래서 this.state.name이렇게 작성한다-->
        <ol class="list-group list-group-numbered">
          <li class="list-group-item">
            <img src={this.state.avatar} alt=""/>
          </li>
          <li class="list-group-item">{this.state.name}</li>
          <li class="list-group-item">{this.state.email}</li>
        </ol>
        <li>
          <Link href = "/"><a>GO HOME</a></Link>
        </li>
        <a href = "/"> Go HOME (without link)</a>
                <!--generate 함수를 호출 하는 button-->
        <button onClick ={this.generate}>generate</button>
      </div>
    );
  }
}

export default About;

이럴 경우 mobx를 사용하는데

mobx: react x, 상태 관리를 위한 라이브러리

README · MobX

먼저 mobx사용을 위해 mobx 와 mobx-react를 사용해준다.

npm add mobx
npm add mobx-react

이때 observer 와 observable로 상태를 나눌 수있는데

observable은 상태가 변경되는 데이터를 정의 해주는 것이고

observer는 이런 상태가 변경되어있는지 관찰하는 함수를 말한다.

위에있는 코드를 mobx로 고치면 아래와 같이 변화 한다.

import Link from 'next/link';
import faker from 'faker';
import React, { Component } from 'react';
import { makeObservable, observable, action } from "mobx";
import {observer} from 'mobx-react';
import { render } from 'react-dom';
class Data{
  avatar = faker.image.avatar();
  email = faker.internet.email();
  name = {
    fristName:faker.name.firstName(),
    lastNmae: faker.name.lastName(),
  };
  
  constructor(value) {
    
    makeObservable(this, {  // 예전 버전의 mobx에서는 decorate 사용,  최신버전에서 makeObservable사용
      avatar: observable,  // observable이니 내가 관찰할 상태 
      email: observable,    // action 이니 상태의 변화를 일으킬 친구
      name: observable,    // action 이니 상태의 변화를 일으킬 친구
    });
}
}

class About extends Component{
  data = new Data;
  generate = () => {
    this.data.avatar = faker.internet.avatar();
    this.data.email=faker.internet.email();
    this.data.name.fristName =faker.name.firstName();
      }
  render(){
    return(
      <div>
        <h1>ABOUTFakerDemo </h1>
        <ol class="list-group list-group-numbered">
          <li class="list-group-item">
            <img src={this.data.avatar} alt=""/>
          </li>
          <li class="list-group-item">{this.data.name.fristName}{this.data.name.lastNmae}</li>
          <li class="list-group-item">{this.data.email}</li>
        </ol>
        <li>
          <Link href = "/"><a>GO HOME</a></Link>
        </li>
        <a href = "/"> Go HOME (without link)</a>
        <button onClick ={this.generate}>generate</button>
      </div>
    );
  }
}

// observer 처리해주겠다는 의미
About = observer(About);
export default About;

이처럼 firstname만 뜨는 것을 볼 수있다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7a99c53a-3ccb-4fd9-b14c-dff80796fa9d/Animation2.gif

decorater를 사용하면 @를 사용하면서 간편하게 dacorate 사용이 가능하다

⇒ 자꾸 에러가 나는 문제 발생... 왜 그러는 거냐

Enabling decorators · MobX

vercel/next.js

https://iiunknown.gitbooks.io/mobxdocen/content/best/decorators.html

React MobX 초심으로 돌아가서 공부하기(MobX최신 버전반영/MobX6)