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){ *state is your redux-store object* return { user:state.activeUser }
export default connect(mapStateToProps)(Userdetails);
用于描述mapstateToProps的bolerplate:
//这是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} />; } } }
问: Is this ok? 答:是的
Is this ok?
问: Is this expected? 是的,这是预期的(如果您使用react-redux)。
Is this expected?
问: Is this an anti-pattern? 答:不,这不是反模式。
Is this an anti-pattern?
它被称为“连接”您的组件或“使其变得聪明”。这是设计的。
它允许您将组件与状态分离一段时间,从而增加代码的模块性。它还允许您将组件状态简化为应用程序状态的子集,这实际上可以帮助您遵守Redux模式。
以这种方式思考:商店应该包含 整个 申请状态。 对于大型应用程序,这可能包含嵌套多层深层的许多属性。 你不想在每次通话时都花费这么多(昂贵的)。
没有 mapStateToProps 或者其中的某些类似物,你会想要用另一种方式来改变你的状态以提高性能/简化。
mapStateToProps
是的,这是正确的。它只是一个辅助函数,可以更简单地访问您的状态属性
想象一下,你有一个 posts 在你的应用程序中键入 state.posts
posts
state.posts
state.posts // /* { currentPostId: "", isFetching: false, allPosts: {} } */
和组件 Posts
Posts
默认情况下 connect()(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())
dispatch(anActionCreator())
同 bindActionCreators 你也可以更容易地做到这一点
bindActionCreators
connect( state => state.posts, dispatch => bindActionCreators({fetchPosts, deletePost}, dispatch) )(Posts)
现在,您可以在Component中使用它
const Posts = ({isFetching, allPosts, fetchPosts, deletePost }) => ( <div> <button onClick={() => fetchPosts()} />Fetch posts</button> {/* access isFetching, allPosts directly */} </div> )
actionCreator的一个示例: deletePost
deletePost
const deletePostAction = (id) => ({ action: 'DELETE_POST', payload: { id }, })
所以, bindActionCreators 只会采取你的行动,包装他们 dispatch 呼叫。 (我没有阅读redux的源代码,但实现可能如下所示:
dispatch
const bindActionCreators = (actions, dispatch) => { return Object.keys(actions).reduce(actionsMap, actionNameInProps => { actionsMap[actionNameInProps] = (...args) => dispatch(actions[actionNameInProps].call(null, ...args)) return actionsMap; }, {}) }
你得到了第一部分:
是 mapStateToProps 将Store状态作为参数/参数(由...提供) react-redux::connect )和它用于链接组件与存储状态的某些部分。
react-redux::connect
通过链接我的意思是返回的对象 mapStateToProps 将在施工时作为道具提供,任何后续更改将通过 componentWillReceiveProps 。
componentWillReceiveProps
如果你知道观察者设计模式,它就是它的那个或小变化。
一个例子将有助于使事情更清楚:
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 )react-redux通过向其发送更改来检测是否存在更改并通知或“发布”所有侦听/订阅组件 componentWillReceiveProps 在这个例子中,由于反应状态已经改变,因此将触发物品的重新过滤并刷新显示。
itemsFilters
filtersComponent
如果这个例子令人困惑或不够清楚,无法提供更好的解释,请告诉我。
至于: 这意味着目标组件所使用的状态与存储在商店中的状态可能具有完全不同的结构。
我没有得到问题,但只知道反应状态( this.setState )与Redux Store状态完全不同!
this.setState
反应状态用于处理反应组分的重绘和行为。反应状态仅包含在组件中。
Redux Store状态是Redux reducer状态的组合,每个状态都负责管理一小部分app逻辑。可以在帮助下访问这些reducers属性 react-redux::connect@mapStateToProps 任何组件!这使得Redux存储状态可以访问应用程序范围,而组件状态是独有的。
react-redux::connect@mapStateToProps
这个 应对 &安培; 终极版 例子是基于Mohamed Mellouki的例子。 但验证使用 美化 和 掉毛规则 。请注意,我们定义了道具 和 调度 方法使用 PropTypes 这样我们的编译器就不会对我们尖叫。 这个例子还包括Mohamed中缺少的一些代码行 例。要使用连接,您需要从中导入 反应-终极版 。这个 例子也 结合 filterItems这个方法会阻止 范围 问题 该 零件 。此源代码已使用JavaScript自动格式化 美化 。
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);
此示例代码是组件起始位置的良好模板。
的 反应 - 终极版 强> connect 用于更新每个操作的存储。
connect
import { connect } from 'react-redux'; const AppContainer = connect( mapStateToProps, mapDispatchToProps )(App); export default AppContainer;
它在这里非常简单明了地解释了 博客 。
您可以克隆github项目或复制粘贴该博客中的代码以了解Redux连接。