Проблемы с использованием действий в презентационном компоненте react-redux

Я новичок в редуксе, и у меня проблемы с презентационными и контейнерными компонентами.

Соответствующий стек:

  • реагировать v0.14.8
  • реагировать родной v0.24.1
  • редукс v3.5.2
  • реакция-редукс v4.4.5

Проблема:

У меня есть компонент кнопки входа в систему, который при отображении проверяет статус входа и вызывает действие onSuccessfulLogin, которое обновляет состояние учетными данными пользователя Facebook.

Однако при попытке разделить это на отдельные компоненты представления/контейнера я не могу вызвать действие onSuccessfulLogin: Error: onSuccessfulLogin is not defined.

Что я здесь делаю неправильно? Я бы предположил, что есть что-то простое, чего я не понимаю в отношениях между двумя компонентами и функцией connect().

Презентационный компонент (Login.js)

import React, { PropTypes } from "react-native";
import FBLogin from "react-native-facebook-login";
import UserActions from "../users/UserActions";

class LoginPage extends React.Component {

    render() {

        const { userData, onSuccessfulLogin } = this.props;

        return (
          <FBLogin
              permissions={["email","user_friends"]}
              onLoginFound= { data => {
                  onSuccessfulLogin(data.credentials);
              }}
              />
        )
    }
};

export default LoginPage;

Компонент-контейнер (LoginContainer.js)

import { connect } from 'react-redux';
import LoginPage from "../login/LoginPage";
import UserActions from "../users/UserActions";

const mapDispatchToProps = (dispatch) => {
  return {
    onSuccessfulLogin: (userData) => {
      dispatch(UserActions.userLoggedIn(userData))
    }
  }
}

const mapStateToProps = (state) => {
  return {
    userData: state.userData
  }
}

const LoginContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(LoginPage);

export default LoginContainer;

Кроме того, если бы я хотел сделать обновленный state.userData доступным для компонента LoginPage, как бы я это сделал? Любая помощь приветствуется!

Решено! При использовании классов ES6 вам необходимо вызвать super(props) в методе конструктора, чтобы получить доступ к свойствам контейнера в подключенном презентационном компоненте:

class LoginPage extends React.Component {
    constructor(props){
        super(props);
    }

    render(){    
        // ...
    }
}

person Andrew    schedule 15.05.2016    source источник


Ответы (1)


Предполагается, что ваш компонент-контейнер является компонентом и должен иметь функцию рендеринга с простыми/презентационными компонентами, которые вы хотите визуализировать.

import { connect } from 'react-redux';
import LoginPage from "../login/LoginPage";
import UserActions from "../users/UserActions";


class LoginContainer extends React.Component {
    constructor(props){
      super(props);
    }
    render() {
        return (
          <LoginPage userData={this.props.userData}
              onSuccessfulLogin={this.props.onSuccessfulLogin}
              />
        )
    }
};

const mapDispatchToProps = (dispatch) => {
  return {
    onSuccessfulLogin: (userData) => {
      dispatch(UserActions.userLoggedIn(userData))
    }
  }
}

const mapStateToProps = (state) => {
  return {
    userData: state.userData
  }
}


export default connect(
  mapStateToProps,
  mapDispatchToProps
)(LoginPage);
person QoP    schedule 15.05.2016
comment
Однако я немного запутался, потому что в документах Redux (redux.js.org/ docs/basics/ExampleTodoList.html), у них есть контейнер (containers/VisibleTodoList.js), который ничего не отображает. Какая разница? - person Andrew; 15.05.2016
comment
хм ... это базовый пример, когда они используют контейнеры только для внедрения состояния и действий, что не является обычным явлением, для более реального примера проверьте github.com/reactjs/redux/tree/master/examples/real-world - person QoP; 15.05.2016
comment
Привет, QoP, спасибо за ваши ответы :) Почему код в моем примере не работает только для ввода состояния и действий? - person Andrew; 16.05.2016
comment
Собственно, я понял это на вашем примере. Я не делал свойства доступными для подключенного компонента. Мне нужно было вызвать super(props) в конструкторе класса. Спасибо за вашу помощь :) - person Andrew; 16.05.2016