kok202
Mobx

2020. 2. 9. 01:46[공부] 영상/React with TS

강의 링크

Mobx 데코레이터

  1. @observable
    클래스의 프로퍼티에만 달 수 있다.
  2. @observer
    클래스에 달아서 처리
    React의 라이프 사이클이 아니라 Mobx의 라이프 사이클을 타게된다.
    • componentWillReact
    • componentWillUpdate
    • componentDidUpdate
  3. @computed
    • observer 와 같은 느낌
    • getter에만 붙일 수 있다.
    • 관찰하고 있는 값이 ~할 때만 렌더링을 해라. 와 같은 로직을 추가할 수 있다.
    • 내부적으로 최적화를 할 수 있게 도와준다.
  4. @action
    • Mobx의 state 를 변경하는 메소드를 action 이라고한다.
    • Store 안에 private 변수가 있을 때에 바깥에서 state 를 변경하려 해도 action 데코레이터를 달아줘야한다.
    • 이 데코레이터는 달아주지 않아도 된다. 하지만 여러모로 쓰는게 이득이다.
    • 이 데코레이터를 달아주면 트랜잭션으로 동작한다.
    • 어떤 메소드에의해 두개의 옵저버블 프로퍼티가 변경이 된다 했을 때, 액션을 달아주지 않으면 렌더링이 두번 발생한다. 액션을 달아주면 1번만 발생한다.
    • mobx의 useStrict 모드를 해주면 action 데코레이터를 달지 않으면 에러가 나게 할 수 있다.
  5. @provider
    • Redux의 프로바이더와 같다.
  6. @inject
    • 프로바이더에 props에 넣고 @inject로 불러온다.

예제

./entity/TodoEntity.tsx

export default class TodoEntity {
        id: string;
        content : string;
}

./stores/TodoStore.tsx

class TodoStore{
    @observable
    public todos : TodoEntity[] = [];

    @action
    public addTodo = (content : string) : void => {
        this.todos.push({
            id : "AAABBB",
            content : content
        })
    }
}

const todoStore  = new TodoSore();
export default TodoStore;
export { todoStore };

Index.tsx

ReactDOM.render(
    <Provider todoStore={todoStore}>
        <App/>
    </Provider>,
    Document.getElementById('root') as HTMLElement
);

AppProps.tsx

export default interface AppProps {
    todoStore? : TodoStore;
}

App.tsx

@inject('todoStore')
@observer
class App extends React.Component<AppProps, {}> {
    render() {
        const todoStore = this.props.todoStore as TodoStore;
        return(
        <div>
            <TodoInput addTodo={store.addTodo} />
            <TodoList todos={store.todos} />
        </div>
        )
    }
}

TodoInputProps.tsx

export default interace TodoInputProps{
    addTodo(text:string) : void;
}

TodoInput.tsx

class TodoInput extends React.Component<TodoInputProps, {}> {
    private inputText : HTMLInputElement;
    private addTodo = () => {
        const inputText = this.inputText.value;
        if(text !== ''){
            this.props.addTodo(inputText);
        }
    }

    render() {
        return(
            <div>
                <input type="text" ref={ref => {this.inputText = ref as HTMLInputElement}}/>
                <button onClick={() => this.addTodo()}> Add </button>
            </div>
        );
    }
}

TodoListProps.tsx

export default interface TodoListProps {
    todos : TodoEntity[];
}

TodoList.tsx

@observer
class TodoList extends React.Component<TodoListProps, {}> {
    render() {
        const list = this.props.todos.map(todo => {
        <li key={todo.id}>
            {todo.text}
        </li>
        });
        return(
            <div>
                {list}
            </div>
        )
    }
}

  1. useStrict 를 쓰자.
  2. provider 와 inject 를 쓰자. 안쓰고 Store 를 싱글톤으로 쓰기 시작하면 복잡도가 올라간다.
  3. Container - Presentational 패턴을 쓰자.
    1. Container
      1. Inject 로 데이터를 가져와 정제
      2. Store 의 값을 변경하는 로직등에도 관여
    2. Presentational
      1. Container 로부터 store 의 값을 전달 받는다.
      2. 전달 받은 값을 어떻게 보여줄지 결정한다.
  4. Reactions 은 되도록 적게 사용하고 사용시에는 이름을 붙이자. 사용한 후에는 반드시 제거한다.

'[공부] 영상 > React with TS' 카테고리의 다른 글

React + Typescript 추가 지식  (0) 2020.02.15