Web Programming

Redux가 필요한 이유

jinmc 2021. 8. 20. 17:23
반응형

참고 자료 : https://blog.logrocket.com/why-use-redux-reasons-with-clear-examples-d21bffd5835/

 

- Redux란 무엇일까요?

state management tool 입니다.

 

- Redux가 필요한 이유

Redux가 없다면, 모든 state들이 서로 통신하기 위해서는 공통의 부모까지 연결해서 다시 property로 내리는 

상황이 반복되어야 할 겁니다.

다음 코드를 보면서 무슨 말인지 알아볼까요?

 

class App extends React.Component {
  constructor(props) {
    super(props);
    // First the Parent creates a state for what will be passed
    this.state = { userStatus: "NOT LOGGED IN"}
    this.setStatus = this.setStatus.bind(this);
  }
  // A method is provided for the child component to update the state of the
  // userStatus
  setStatus(username, password) {
    const newUsers = users;
    newUsers.map(user => {
      if (user.username == username && user.password === password) {
        this.setState({
          userStatus: "LOGGED IN"
        })
      }
    });
  }
 
  render() {
    return (
      <div>
        // the state is passed to the sibling as a props as is updated whenever
        // the child component changes the input
        <Status status={this.state.userStatus} />
        // this method is passed to the child component as a props which it
        // uses to change the state of the userStatus
        <Login handleSubmit={this.setStatus} />
      </div>
    );
  }
});

로그인이 성공하였을 때, 다른 페이지로 redirecting하는 방법도 물론 있겠지만, 

성공하였다는 App의 state을 property로 내려주어서 Status에서 사용하는 경우도 있을 것입니다.

간단한 예여서 쉽게 느껴질 수 있지만, DOM tree가 복잡한 경우에는, 공통의 부모까지 어떻게든 찾아서, 

거기에서 state을 내려주어야 한다는 점에서, inefficient한 구조라고 볼 수 있을 것 같습니다.

 

action과  action creator를 만들어 줘야 합니다.

{ 
  type: "LOGIN",
  payload: {
    username: "foo",
    password: "bar"
  }
}

위 코드는 action이고,

const setLoginStatus = (name, password) => {
  return {
    type: "LOGIN",
    payload: {
      username: "foo",
      password: "bar"
    }
  }
}

 위 코드는 action creator입니다. 

 

Redux를 이용하면, 이런 구조를 바꿀 수 있습니다. 

Reducer를 이용해서 다음과 같은 코드를 만들 수 있습니다.

const LoginComponent = (state = initialState, action) => {
    switch (action.type) {

      // This reducer handles any action with type "LOGIN"
      case "LOGIN":
          return state.map(user => {
              if (user.username !== action.username) {
                  return user;
              }

              if (user.password == action.password) {
                  return {
                      ...user,
                      login_status: "LOGGED IN"
                  }
              }
          });
default:
          return state;
      } 
};

위 코드에서 하는 일은, action Login이 들어왔을 때 어떤 global state를 return하는 것입니다.

이를 활용하면, App에서 굳이 Status 에 내려줄 필요가 없습니다.

 

class App extends React.Component {
    render() {
        return (
            <div>
                <Status user={this.props.user.name}/>
                <Login login={this.props.setLoginStatus}/>
            </div>
        )
    }
}

 

- Redux 구조

Action, Reducer, Store, 등이 필요합니다.

Action은 Event로써, user interaction이나, API 콜, 등이 있습니다.

Action은 store에서 dispatch 를 부름으로써 Store를 사용합니다.

Redux에서는 State를 global state로 하나만 사용하고, Store도 하나만 사용합니다.

Reducer에서는, state을 복사하고 새로운 state을 만드는 것으로 (기존 내용 복사) 새로운 state를 return합니다.

여기서  reducer의 역할은, pure function으로, 같은 값이 들어오면, 같은 값이 나가야 됩니다. 

또한, 비동기적인 콜은 할 수 없습니다 (http call 같은)

 

 

React를 사용하는 것의 장점

- 속도 : global state를 사용함으로써 더 느려지지 않을까 걱정할 수 있지만, 실은 내부 optimization으로 더 빠르다고 합니다.

- 테스팅 용이 : global state을 사용하여 테스팅이 용이합니다.

- 디버깅 용이 : previous state와 next state를 사용하여 디버깅이 용이합니다.

- state를 예상 가능하게 합니다 (predictable) action을 기준으로 전후로 돌아가는 (undo, redo) 의 동작도 용이합니다.

 

 

 

 

반응형