Programing

React-Redux 및 mapStateToProps () 이해

lottogame 2020. 5. 11. 07:58
반응형

React-Redux 및 mapStateToProps () 이해


react-redux의 연결 방법과 매개 변수로 사용되는 기능을 이해하려고합니다. 특히 mapStateToProps().

내가 이해하는 방식의 반환 값은 mapStateToProps상태 (상점에있는 상태)에서 파생 된 객체이며 키는 대상 구성 요소 (구성 요소 연결이 적용됨)에 소품으로 전달됩니다.

이는 대상 구성 요소가 소비 한 상태가 상점에 저장된 상태와 크게 다른 구조를 가질 수 있음을 의미합니다.

Q : 괜찮습니까?
Q : 이것이 예상됩니까?
Q : 반 패턴입니까?


Q : Is this ok?
A : 예

Q : Is this expected?
그렇습니다 (react-redux를 사용하는 경우).

Q : Is this an anti-pattern?
A : 아니요. 이것은 안티 패턴이 아닙니다.

구성 요소를 "연결"또는 "스마트하게 만들기"라고합니다. 의도적으로 설계된 것입니다.

코드의 모듈성을 증가시키는 추가 시간 동안 구성 요소를 상태에서 분리 할 수 ​​있습니다. 또한 구성 요소 상태를 응용 프로그램 상태의 하위 집합으로 단순화하여 실제로 Redux 패턴을 준수하는 데 도움이됩니다.

이 방법에 대해 생각해보십시오. 상점은 애플리케이션 전체 상태 를 포함 해야합니다.
대규모 응용 프로그램의 경우 여기에는 여러 계층 깊이에 중첩 된 수십 가지 속성이 포함될 수 있습니다.
각 통화마다 모든 것을 운반하고 싶지 않습니다 (비싼).

없이 mapStateToProps또는 일부 아날로그 그, 당신은 당신의 상태 / 성능 향상을 단순화하는 또 다른 방법을 개척하는 유혹 될 것이다.


예, 맞습니다. 상태 속성에 더 간단하게 액세스 할 수있는 도우미 함수일뿐입니다.

posts앱에 키 가 있다고 상상해보십시오state.posts

state.posts //
/*    
{
  currentPostId: "",
  isFetching: false,
  allPosts: {}
}
*/

그리고 구성 요소 Posts

기본적으로 connect()(Posts)연결된 구성 요소에서 모든 상태 소품을 사용할 수 있습니다.

const Posts = ({posts}) => (
  <div>
    {/* access posts.isFetching, access posts.allPosts */}
  </div> 
)

이제 state.posts구성 요소에 매핑하면 조금 더 좋아집니다.

const Posts = ({isFetching, allPosts}) => (
  <div>
    {/* access isFetching, allPosts directly */}
  </div> 
)

connect(
  state => state.posts
)(Posts)

mapDispatchToProps

일반적으로 당신은 작성해야 dispatch(anActionCreator())

bindActionCreators당신 과 함께 더 쉽게 할 수 있습니다

connect(
  state => state.posts,
  dispatch => bindActionCreators({fetchPosts, deletePost}, dispatch)
)(Posts)

이제 컴포넌트에서 사용할 수 있습니다

const Posts = ({isFetching, allPosts, fetchPosts, deletePost }) => (
  <div>
    <button onClick={() => fetchPosts()} />Fetch posts</button>
    {/* access isFetching, allPosts directly */}
  </div> 
)

actionCreators에 대한 업데이트 ..

actionCreator의 예 : deletePost

const deletePostAction = (id) => ({
  action: 'DELETE_POST',
  payload: { id },
})

그래서, bindActionCreators당신의 행동을 취하고 그들을 dispatch전화 로 포장합니다 . (저는 redux의 소스 코드를 읽지 않았지만 구현은 다음과 같습니다.

const bindActionCreators = (actions, dispatch) => {
  return Object.keys(actions).reduce(actionsMap, actionNameInProps => {
    actionsMap[actionNameInProps] = (...args) => dispatch(actions[actionNameInProps].call(null, ...args))
    return actionsMap;
  }, {})
}

첫 번째 부분이 맞았습니다.

mapStateToProps는 상점 상태를 인수 / 매개 변수 (로 제공 react-redux::connect)로 가지며 구성 요소를 상점 상태의 특정 부분과 링크하는 데 사용됩니다.

연결한다는 것은 mapStateToProps건설 시간에 소품으로 반환되는 물건이 소품으로 제공되며 이후의 모든 변경 사항은를 통해 제공됨을 의미 componentWillReceiveProps합니다.

Observer 디자인 패턴을 알고 있다면 정확히 그 또는 작은 변형입니다.

예를 들어 더 명확하게하는 데 도움이됩니다.

import React, {
    Component,
} from 'react-native';

class ItemsContainer extends Component {
    constructor(props) {
        super(props);

        this.state = {
            items: props.items, //provided by connect@mapStateToProps
            filteredItems: this.filterItems(props.items, props.filters),
        };
    }

    componentWillReceiveProps(nextProps) {
        this.setState({
            filteredItems: this.filterItems(this.state.items, nextProps.filters),
        });
    }

    filterItems = (items, filters) => { /* return filtered list */ }

    render() {
        return (
            <View>
                // display the filtered items
            </View>
        );
    }
}

module.exports = connect(
    //mapStateToProps,
    (state) => ({
        items: state.App.Items.List,
        filters: state.App.Items.Filters,
        //the State.App & state.App.Items.List/Filters are reducers used as an example.
    })
    // mapDispatchToProps,  that's another subject
)(ItemsContainer);

There can be another react component called itemsFilters that handle the display and persisting the filter state into Redux Store state, the Demo component is "listening" or "subscribed" to Redux Store state filters so whenever filters store state changes (with the help of filtersComponent) react-redux detect that there was a change and notify or "publish" all the listening/subscribed components by sending the changes to their componentWillReceiveProps which in this example will trigger a refilter of the items and refresh the display due to the fact that react state has changed.

Let me know if the example is confusing or not clear enough to provide a better explanation.

As for: This means that the state as consumed by your target component can have a wildly different structure from the state as it is stored on your store.

I didn't get the question, but just know that the react state (this.setState) is totally different from the Redux Store state!

The react state is used to handle the redraw and behavior of the react component. The react state is contained to the the component exclusively.

The Redux Store state is a combination of Redux reducers states, each is responsible of managing a small portion app logic. Those reducers attributes can be accessed with the help of react-redux::connect@mapStateToProps by any component! Which make the Redux store state accessible app wide while component state is exclusive to itself.


This react & redux example is based off Mohamed Mellouki's example. But validates using prettify and linting rules. Note that we define our props and dispatch methods using PropTypes so that our compiler doesn't scream at us. This example also included some lines of code that had been missing in Mohamed's example. To use connect you will need to import it from react-redux. This example also binds the method filterItems this will prevent scope problems in the component. This source code has been auto formatted using JavaScript Prettify.

import React, { Component } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

class ItemsContainer extends Component {
  constructor(props) {
    super(props);
    const { items, filters } = props;
    this.state = {
      items,
      filteredItems: filterItems(items, filters),
    };
    this.filterItems = this.filterItems.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const { itmes } = this.state;
    const { filters } = nextProps;
    this.setState({ filteredItems: filterItems(items, filters) });
  }

  filterItems = (items, filters) => {
    /* return filtered list */
  };

  render() {
    return <View>/*display the filtered items */</View>;
  }
}

/*
define dispatch methods in propTypes so that they are validated.
*/
ItemsContainer.propTypes = {
  items: PropTypes.array.isRequired,
  filters: PropTypes.array.isRequired,
  onMyAction: PropTypes.func.isRequired,
};

/*
map state to props
*/
const mapStateToProps = state => ({
  items: state.App.Items.List,
  filters: state.App.Items.Filters,
});

/*
connect dispatch to props so that you can call the methods from the active props scope.
The defined method `onMyAction` can be called in the scope of the componets props.
*/
const mapDispatchToProps = dispatch => ({
  onMyAction: value => {
    dispatch(() => console.log(`${value}`));
  },
});

/* clean way of setting up the connect. */
export default connect(mapStateToProps, mapDispatchToProps)(ItemsContainer);

This example code is a good template for a starting place for your component.


React-Redux connect is used to update store for every actions.

import { connect } from 'react-redux';

const AppContainer = connect(  
  mapStateToProps,
  mapDispatchToProps
)(App);

export default AppContainer;

It's very simply and clearly explained in this blog.

You can clone github project or copy paste the code from that blog to understand the Redux connect.


Here's an outline/boilerplate for describing the behavior of mapStateToProps:

(This is a vastly simplified implementation of what a Redux container does.)

class MyComponentContainer extends Component {
  mapStateToProps(state) {
    // this function is specific to this particular container
    return state.foo.bar;
  }

  render() {
    // This is how you get the current state from Redux,
    // and would be identical, no mater what mapStateToProps does
    const { state } = this.context.store.getState();

    const props = this.mapStateToProps(state);

    return <MyComponent {...this.props} {...props} />;
  }
}

and next

function buildReduxContainer(ChildComponentClass, mapStateToProps) {
  return class Container extends Component {
    render() {
      const { state } = this.context.store.getState();

      const props = mapStateToProps(state);

      return <ChildComponentClass {...this.props} {...props} />;
    }
  }
}

import React from 'react';
import {connect} from 'react-redux';
import Userlist from './Userlist';

class Userdetails extends React.Component{

render(){
    return(
        <div>
            <p>Name : <span>{this.props.user.name}</span></p>
            <p>ID : <span>{this.props.user.id}</span></p>
            <p>Working : <span>{this.props.user.Working}</span></p>
            <p>Age : <span>{this.props.user.age}</span></p>
        </div>
    );
 }

}

 function mapStateToProps(state){  
  return {
    user:state.activeUser  
}

}

  export default connect(mapStateToProps, null)(Userdetails);

참고URL : https://stackoverflow.com/questions/38202572/understanding-react-redux-and-mapstatetoprops

반응형