Redux Connect:mapDispatchToProps传递操作创建者的结果

时间:2020-10-15 10:40:44

标签: redux react-redux

我正在学习redux,并且想知道如何执行动作创建者的调度,如以下从redux文档中截取的屏幕截图所述。

可在此处获得学习应用程序的代码:https://github.com/ZhangMYihua/lesson-12/tree/master/src

根据课程讲师,以下mapDispatchToProps代码使用user.action.js更新标题组件的状态。即使阅读了Redux文档,我也无法理解所有这些工作原理.https://react-redux.js.org/using-react-redux/connect-mapdispatch

const mapDispatchToProps = dispatch => ({
  setCurrentUser: user => dispatch(setCurrentUser(user))
});
  1. 头文件组件中currentUser的初始状态是使用redux文件夹中的user.reducer.js文件设置的。这部分很清楚。
  2. 当我们使用Google登录登录时,App.js中的createUserProfileDocument(userAuth)函数将检查firestore用户集合中是否提供了Google登录名。如果没有,它将使用所需字段创建帐户的副本。用户登录详细信息是从Firestore用户集合中获取的,这些集合在App.js的userRef中传递。

我不明白的是,当我们使用Google登录登录时,如何通过调度将来自componentDidMount()中userRef的数据传递给标头组件?

componentDidMount() {

    const {setCurrentUser} = this.props;

    this.unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => {

     if (userAuth) {
       const userRef = await createUserProfileDocument(userAuth);

       userRef.onSnapshot(snapShot => {
         setCurrentUser({
             id: snapShot.id,
             ...snapShot.data()
           });
         });

     }

下面是react-redux文档中的示例,与上面类似。

enter image description here

1 个答案:

答案 0 :(得分:0)

您的componentDidMount中的这一部分正在将userRef数据传递到redux存储:

const {setCurrentUser} = this.props;

// ...

setCurrentUser({
  id: snapShot.id,
  ...snapShot.data()
});

mapDispatchToProps

代码调用this.props.setCurrentUser,这是您在mapDispatchToProps中定义的函数。

const mapDispatchToProps = dispatch => ({
  setCurrentUser: user => dispatch(setCurrentUser(user))
});

因此this.props.setCurrentUser函数定义很简单(其中,dispatch在较高范围内定义):

this.props.setCurrentUser = user => dispatch(setCurrentUser(user))

该函数采用单个参数user并调用dispatch(setCurrentUser(user))setCurrentUser(user)是您的动作创建者,可以产生一些动作(类似{action: 'SET_CURRENT_USER', payload: {user}})。此操作通过redux函数分发到dispatch存储区(react-redux通过dispatch {{1}将正确的mapDispatchToProps函数传递给您的react-redux },请参见下面)。

连接

如果您不将connect用作mapDispatchToProps react-redux函数的参数,则它是无用的。通常,您用connect包装组件,然后导出包装的组件而不只是组件本身。因此,每当您导入App.js模块并将其默认导出用作某些JSX树中的组件时,它不仅是您的组件,而且是用connect魔术包裹的组件。这种魔力确保使用正确的调度参数(来自react-redux库的store.dispatch来调用mapDispatchToProps),并使用其他属性(组成redux的属性和来自{的属性)增强组件props对象。 {1}}。

mapStateToProps

在下一个文件中,您将导入并使用包装后的组件,如下所示:

mapDispatchToProps

有必要将使用// here you are wrapping your App component with `connect` from `react-redux` export default connect( null, mapDispatchToProps )(App); 的组件和Provider一起包装在应用程序组件树中。否则import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import store from './redux/store'; import App from './App'; // here you are importing the wrapped component ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ); 将无权访问react-redux存储,因此组件连接到connect存储将不起作用。

编辑

mapStateToProps

redux用于将操作分派到仅修改它的redux存储中(如何修改存储取决于您对redux的实现-请参见示例中的user.reducer.js)。

如果要访问this.props.setCurrentUser存储区的某些部分,则需要在第一个参数前传递reducer(请参见上面的示例,在redux组件的示例中,第一个参数mapStateToProps中的App)。

您可以将redux存储想象为单个javascript对象。您可以在root-reducer.js中看到该对象的第一个定义:

connect

这定义您的null商店(对象)在顶层具有属性export default combineReducers({ user: userReducer }); 。属性redux的值处理user.reducer.js。该reducer定义了商店user部分的初始值,并且还定义了如何修改它(通过redux动作)。因此,根据您的示例,您的初始商店是这样的:

user

如果要在组件(props)中访问它,则需要使用user,如上所述(请参见示例中的文件header.component.jsx

{
  user:  {
    currentUser: null
  }
}

然后通过props访问组件中已连接的存储值:

mapStateToProps