我试图理解react-redux的连接方法,以及它作为参数的函数。特别是mapStateToProps()。

我理解它的方式,mapStateToProps的返回值将是一个从状态派生的对象(因为它存在于存储中),它的键将作为道具传递给您的目标组件(组件连接被应用到)。

这意味着目标组件使用的状态可能与存储在存储库中的状态具有完全不同的结构。

问:这样可以吗? 问:这是预期的吗? 问:这是反模式吗?


当前回答

React-Redux连接用于更新每个操作的存储。

import { connect } from 'react-redux';

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

export default AppContainer;

这篇博客里解释得非常简单明了。

你可以克隆github项目或复制粘贴从博客的代码来理解Redux连接。

其他回答

下面是描述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} />;
    }
  }
}

React-Redux连接用于更新每个操作的存储。

import { connect } from 'react-redux';

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

export default AppContainer;

这篇博客里解释得非常简单明了。

你可以克隆github项目或复制粘贴从博客的代码来理解Redux连接。

It's a simple concept. Redux creates a ubiquitous state object (a store) from the actions in the reducers. Like a React component, this state doesn't have to be explicitly coded anywhere, but it helps developers to see a default state object in the reducer file to visualise what is happening. You import the reducer in the component to access the file. Then mapStateToProps selects only the key/value pairs in the store that its component needs. Think of it like Redux creating a global version of a React component's

this.state = ({ 
cats = [], 
dogs = []
})

不可能通过使用mapStateToProps()来改变状态的结构。您所做的只是选择组件需要的存储键/值对,并将值(从存储中的键/值列表中)传递给组件中的道具(本地键)。在列表中,每次只执行一个值。在此过程中不会发生结构更改。

附注:商店是本地的。reducer通常也将状态传递给数据库,与Action creator一起混合,但首先要理解这个简单的概念。

P.P.S.将每个减速器分离到单独的文件中,并且只导入组件需要的减速器,这是一个很好的做法。

是的,这是正确的。它只是一个帮助函数,有一个更简单的方法来访问你的状态属性

假设你在App state.posts中有一个posts键

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

和组件职位

默认情况下,connect()(Posts)将使连接组件的所有状态道具可用

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

现在当你绘制州地图。post到你的组件会更好一些

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 },
})

bindactioncreator会接受你的动作,把它们包装到分派调用中。(我没有阅读redux的源代码,但实现可能是这样的:

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

我想对你提到的发言进行调整,即:

这意味着您的目标组件所使用的状态可以 与存储时的状态有很大不同的结构 你的商店

可以说,目标组件使用的状态有一小部分状态存储在redux存储区中。换句话说,组件使用的状态是redux存储区状态的子集。

就connect()方法的理解而言,它相当简单!Connect()方法可以向组件添加新道具,甚至覆盖现有道具。通过这个connect方法,我们也可以访问由Provider抛出给我们的redux存储的状态。两者的结合对您有利,您可以将redux存储的状态添加到组件的道具中。

以上是一些理论,我建议你看一遍这个视频来更好地理解语法。