[컴][js] react-redux 사용

redux / flux 사용 / typescript 로 react-redux 사용하기 / redux-thunk / thunk



react-redux

react-redux 설치

npm install --save redux
npm install --save react-redux

typescript 를 사용한다면 아래도 같이 설치해 주자.
npm install --save-dev @types/react-redux


react-redux 사용

  1. event 를 발생시키고 싶은 component 에서 this.props.dispatch(event) 를 이용해서 event 를 발생시킨다. 그리고 이 event 가 store 내에서 다른 component 로 전달되게 하기 위해서 connect() 를 해준다.
    • export const Hello2 = connect()(HelloEveryone)
  2. 이 event 가 어떤 event 인가는 action.js(또는 ts) 로 만들어준다.
  3. 그리고 이 action type 에 따라 어떤 동작을 할지를 정해준다. 이것을 reducer 에서 해준다. 이 reducer 는 나중에 store 를 생성할때 parameter 로 넘겨준다.
  4. 이 reducer 에서 return 해주는 값에 대해 특정 component 에게 어떤 동작을 하게 하고 싶다면, 이 component 가 값에 대해 동작하도록 wrapper function 을 하나 만들어준다. 이녀석은 connect() 를 이용하게 된다.
    • connect(mapStateToProps, mapDispatchToProps)(component) 
  5. 이 event 를 주고 받는 component 를 하나의 component 로 묶는다. 그리고 이것을 <Provider store={}> 로 묶어준다.
  6. store 는 createStore(reducer) 를 이용해서 만들어준다.
    1. let store = createStore(todoApp)
자세한 source 는 여기 를 참고하자.



connect - subscribe, dispatch

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
이것을 사용하기 위해서는 event 가 왔을때 component 의 변경되어야 하는 부분이 props 로 넘겨져야 한다. 즉, component 가 정말 view 의 역할만 하면 된다.
  • mapStateToProps
    • 만약 component 로 event가 왔을 때 변경되어야 하는 prop 값을 return 해주면 된다.
    • subscribe(or listener) 에 해당하는 역할이라고 보면 된다.
  • mapDispatchToProps 
    • component 로 event 가 왔을때 dispatch 를 해야 하는 prop(새로운 action 을 발생시켜야)이 있다면 이곳에서 해당하는 prop 값을 정의해 주면 된다.
    • dispatch 를 발생시키는 역할이라고 보면 된다.

example

아래 2개의 source 를 보면 이해가 좀 된다.

위의 코드에서 TodoList component 는 props 으로
  1. 어떤 이벤트를 보여줄지에대한 prop 과 
  2. todolist 가 click 됐을때의 event handler 에 대한 prop을

가지고 있다. 이 TodoList component 가 event 를 받아서 todolist 를 변경하거나, 새로운 동작을 실행할 수 있도록 하는 부분을 VisibleTodoList 가 가지고 있다.
그리고 이 2개의 object 를 연결시키기 위해 아래처럼 connect 를 해주고 있다.
const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)




source



reducers

  1. store 에서 사용할 reducer 를 만든다. reducer 가 dispatch 된 action 에 알맞는 state 값을 return 하게 된다. 이 return state 가 mapStateToProps 의 parameter 로 넘어간다.
    import { combineReducers } from 'redux'
    var msg_id = 0;
    export const messagePanel = (state: any = {}, action:any) => {
        switch (action.type) {
            case 'SHOW_MESSAGE':
                return {
                    text: '',
                    msg_id : msg_id++,
                }
            case 'CLEAR_MESSAGE':
                return {
                    text: '',
                }
            default:
                return state
        }
    }
    
    
    export const adminreg = combineReducers({
        messagePanel,
    })
    
  2. store 를 만들어서 와 함께 원하는 곳에 놓는다.
    let store = createStore(adminreg)
    ...
    export default class BodyWithProvider extends React.Component<AdminItemRegisterBodyProps, AdminItemRegisterBodyState> {
    
        fireComponentWrapper: any;
        listenerComponentWrapper: any;
    
        constructor(props: any){
            super(props);
            this.state = {
                
            }
            this.pid = this._getProductIdx();
            
            let mapStateToProps = (state: any)=>{
                // state : from reducer `adminreg`
                // msg : prps of `listenerComponent`
                return {
                    msg: state.text,
                }
            }
            // dispatcher
            this.fireComponentWrapper = connect()(FireComponent); 
            // listener
            this.listenerComponentWrapper = connect(mapStateToProps)(ListenerComponent);
        }
    
    
        render(){
            return(
                <Provider store={store}>
                    <div className="col-lg-12">
                        <this.listenerComponentWrapper />
                        <this.fireComponentWrapper productIdx={this.pid}/>
                        {/* <WorkTime /> */}
                    </div>
                </Provider>
    
                
            )
        }
    
        ...
    

dispatch component

  1. event 를 fire 하고 싶은 component 를 connect() 로 연결하자.
    import {connect} from 'react-redux';
    ...
    var a = connect()(FireComponent);
    
  2. props 에 DispatchProp 를 추가한다.
    import {DispatchProp} from 'react-redux';
    ...
    export interface FireComponentProps extends React.Props<any>, DispatchProp<any>{
    }
    
  3. event 를 dispatch 한다. 이 때 이 event 는 하나의 .ts(.js) 로 모아서 import 해서 사용할 수 있다.
    if(this.props.dispatch){
        this.props.dispatch({
      type: 'SHOW_MESSAGE',
     })
    }
    

listener component

  1. listenrComponent Props 값을 정해 준다.
    export interface listenerComponentProps extends React.Props<any>{
        listenerProp: number,
    }
    
  2. listener Component 를 connect() 한다. 이 때 mapStateToProps 를 설정해 준다. return 값에 listener Component 로 pass 할 새로운 prop 값이 설정되도록 하면 된다.
    let mapStateToProps = (state: any)=>{
        // state : from reducer `adminreg`
        // msg : prps of `listenerComponent`
        return {
            msg: state.messagePanel.text,
        }
    }
    
    this.listenerComponentWrapper = connect(mapStateToProps)(listenerComponent);
    


See Also

  1. 쿠...sal: [컴][자바스크립트] 간단한 Redux 사용 설명
  2. react-redux/api.md at master · reactjs/react-redux · GitHub
  3. What the heck is a 'thunk'?

댓글 없음:

댓글 쓰기