[javascript] 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);
itemsFilters
디스플레이를 처리하고 필터 상태를 Redux Store 상태로 유지하는 다른 반응 구성 요소가있을 수 있습니다 . Demo 구성 요소는 Redux Store 상태 필터를 “청취”또는 “구독”하여 필터 저장 상태가 변경 될 때마다 ( filtersComponent
반응 을 통해 ) 반응합니다 -redux는 변경 사항이 있음을 감지 componentWillReceiveProps
하고이 예에서 항목의 재 필터링을 트리거하고 반응 상태가 변경되어 디스플레이를 새로 고치는 변경 사항을 변경 사항으로 전송하여 청취 / 구독 된 모든 구성 요소에 알리거나 “게시”합니다. .
더 나은 설명을 제공하기에 예제가 혼란 스럽거나 명확하지 않은 경우 알려주십시오.
대상 : 대상 구성 요소가 소비 한 상태가 상점에 저장된 상태와 크게 다른 구조를 가질 수 있음을 의미합니다.
나는 질문을 얻지 못했지만 반응 상태 ( this.setState
)가 Redux Store 상태와 완전히 다릅니다.
반응 상태는 반응 구성 요소의 다시 그리기 및 동작을 처리하는 데 사용됩니다. 반응 상태는 구성 요소에 독점적으로 포함됩니다.
Redux Store 상태는 Redux 감속기 상태의 조합이며 각각 작은 부분의 앱 논리를 관리합니다. 이러한 감속기 속성은 react-redux::connect@mapStateToProps
모든 구성 요소 의 도움으로 액세스 할 수 있습니다 ! 구성 요소 상태가 독점적 인 반면 Redux 스토어 상태 액세스 가능한 앱을 넓게 만듭니다.
답변
이 반응 & redux 예제는 Mohamed Mellouki의 예제를 기반으로합니다. 그러나 prettify 및 linting 규칙을 사용하여 유효성을 검사 합니다. 컴파일러가 소리를 내지 않도록 PropTypes를 사용하여 props 및 dispatch 메소드를 정의 하십시오. 이 예제에는 Mohamed의 예제에서 누락 된 일부 코드 줄도 포함되었습니다. connect를 사용하려면 react-redux 에서 가져와야합니다 . 이 예제는 또한 filterItems 메소드를 바인드 하여 컴포넌트의 범위 문제점을 방지 합니다 . 이 소스 코드는 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);
이 예제 코드는 구성 요소의 시작 위치에 적합한 템플릿입니다.
답변
React-Redux connect
는 모든 작업에 대한 저장소를 업데이트하는 데 사용됩니다.
import { connect } from 'react-redux';
const AppContainer = connect(
mapStateToProps,
mapDispatchToProps
)(App);
export default AppContainer;
이 블로그 에서 매우 간단하고 명확하게 설명되어 있습니다.
Redux 연결을 이해하기 위해 github 프로젝트를 복제하거나 해당 블로그의 코드를 복사하여 붙여 넣을 수 있습니다.
답변
다음은 동작을 설명하기위한 개요 / 보일러 판입니다 mapStateToProps
.
(이것은 Redux 컨테이너의 기능을 대폭 단순화 한 것입니다.)
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} />;
}
}
그리고 다음
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);