Redux - mapDispatchToProps не работает для функции выхода

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

Это компонент «Nav.jsx», в который импортируется действие выхода.

import React from 'react'
import {connect} from 'react-redux'
import {Link} from 'react-router-dom'
import {logoutUser} from '../actions/logout'

class Nav extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      showBurger: false,
      loggedOut: false
    }
    this.toggleBurger = this.toggleBurger.bind(this)
    this.logout = this.logout.bind(this)
  }
  toggleBurger() {
    this.setState({showBurger: !this.state.showBurger})
  }

  logout () {
    this.props.dispatch(logoutUser())
    this.setState({loggedOut: true})
  }

  render() {
    //
    const {auth} = this.props
    const {showBurger} = this.state
    const {loggedOut} = this.state
    console.info("is this logout?", this.logout.bind(this))

    return <nav className = "navbar">
      <div className = "container">
        <div className = "navbar-brand">
          <span onClick = {this.toggleBurger} className = {`navbar-burger burger ${showBurger ? 'is-active': ''}`} data-target = "navbarMenuHeroA">
            <span></span>
            <span></span>
            <span></span>
          </span>
        </div>
        <div id = "navbarMenuHeroA" className = {`navbar-menu ${showBurger ? "is-active" : ''}`}>
          <div className = "navbar-end">
            <Link onClick = {this.toggleBurget} className = "navbar-item" to='/found'>Found</Link>
            <Link onClick = {this.toggleBurget} className = "navbar-item" to='/lost'>Lost</Link>
            {auth.isAuthenticated
              ? <span>
                <Link onClick = {this.toggleBurget} className = "navbar-item" to='/foundform'>Foundform</Link>
                <Link onClick = {this.toggleBurget} className = "navbar-item" to='/lostform'>Lostform</Link>
                <Link to = "/" onClick = {() => this.logout.bind(this)} className = "navbar-item">Logout</Link>
              </span>
              : [
                <Link onClick = {this.toggleBurger} className = "navbar-item is-large" to='/login'>Login</Link>,
                <Link onClick = {this.toggleBurger} className = "navbar-item" to='/register'>Register</Link>,
              ]
            }
          </div>
        </div>
      </div>
    </nav>
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    logout: () => dispatch(logoutUser())
  }
}

const mapStateToProps = ({auth}) => {
  return {auth}
}

export default connect(mapStateToProps, mapDispatchToProps)(Nav)

Когда я запускаю это, console.info сообщает мне: «Это выход из системы? Ƒ () {[native code]}», и я также получаю это предупреждение: «Хеш-история не может PUSH по тому же пути; новая запись не будет добавлена ​​в стек истории ". Это был групповой проект, над которым я сейчас работаю, и я не могу сказать, что именно не так? Пожалуйста помоги.

Вот действие выхода, если это поможет.

   import { removeUser } from '../utils/auth'
    function requestLogout () {
      return {
        type: 'LOGOUT_REQUEST',
        isFetching: true,
        isAuthenticated: true
      }
    }

    function receiveLogout () {
      return {
        type: 'LOGOUT_SUCCESS',
        isFetching: false,
        isAuthenticated: false
      }
    }

    // Logs the user out
    export function logoutUser () {
      return dispatch => {
        document.location = "/#/"
        dispatch(requestLogout())
        removeUser()
        dispatch(receiveLogout())
      }
    }

Вот еще несколько файлов из приложения. Это auth.js в папке redurs.

import { isAuthenticated, getUserTokenInfo } from '../utils/auth'

const initialState = {
  isFetching: false,
  isAuthenticated: isAuthenticated(),
  user: getUserTokenInfo(),
  errorMessage: ''
}

export default function auth (state = initialState, action) {
  switch (action.type) {
    case 'LOGIN_REQUEST':
      return {
        ...state,
        isFetching: true,
        isAuthenticated: false,
        errorMessage: ''
      }
    case 'LOGIN_SUCCESS':
      return {
        ...state,
        isFetching: false,
        isAuthenticated: true,
        user: action.user
      }
    case 'LOGIN_FAILURE':
      return {
        ...state,
        isFetching: false,
        isAuthenticated: false,
        errorMessage: action.message
      }
    case 'LOGOUT_SUCCESS':
      return {
        ...state,
        isFetching: false,
        isAuthenticated: false,
        user: null
      }
    case 'REGISTER_REQUEST':
      return {
        ...state,
        isFetching: true,
        isAuthenticated: false,
        errorMessage: ''
      }
    case 'REGISTER_FAILURE':
      return {
        ...state,
        isFetching: false,
        isAuthenticated: false,
        errorMessage: action.message
      }
    default:
      return state
  }
}

И index.js, где были объединены редукторы.

импортировать {combReducers} из "redux"

import auth from './auth'
import lostPets from './lostPets'
import found from './foundPets'

export default combineReducers({
  auth,
  found,
  lostPets
})
logoutUser - это вызов API или просто функция
RIYAJ KHAN 07.06.2018 13:00

Вы сопоставили свою отправку с реквизитами, поэтому вы не можете использовать this.props.dispatch в этом компоненте. Учитывая это, вы должны использовать this.props.logout вместо своей функции logout(). Попробуйте обновить свой код и посмотрите, что произойдет. Кроме того, похоже, что у вас проблема с react-router.

ionizer 07.06.2018 13:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
1 377
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужно вызвать функцию напрямую, а не использовать диспетчеризацию, поскольку вы уже используете mapDispatchToProps. Если вы не предоставите mapDispatchToProps, dispatch будет доступен для компонента.

import React from 'react'
import {connect} from 'react-redux'
import {Link} from 'react-router-dom'
import {logoutUser} from '../actions/logout'

class Nav extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      showBurger: false,
      loggedOut: false
    }
    this.toggleBurger = this.toggleBurger.bind(this)
    this.logout = this.logout.bind(this)
  }
  toggleBurger() {
    this.setState({showBurger: !this.state.showBurger})
  }

  logout () {
    this.props.logout() // call logout here from props
    this.setState({loggedOut: true})
  }

  render() {
    //
    const {auth} = this.props
    const {showBurger} = this.state
    const {loggedOut} = this.state
    console.info("is this logout?", this.logout.bind(this))

    return <nav className = "navbar">
      <div className = "container">
        <div className = "navbar-brand">
          <span onClick = {this.toggleBurger} className = {`navbar-burger burger ${showBurger ? 'is-active': ''}`} data-target = "navbarMenuHeroA">
            <span></span>
            <span></span>
            <span></span>
          </span>
        </div>
        <div id = "navbarMenuHeroA" className = {`navbar-menu ${showBurger ? "is-active" : ''}`}>
          <div className = "navbar-end">
            <Link onClick = {this.toggleBurget} className = "navbar-item" to='/found'>Found</Link>
            <Link onClick = {this.toggleBurget} className = "navbar-item" to='/lost'>Lost</Link>
            {auth.isAuthenticated
              ? <span>
                <Link onClick = {this.toggleBurget} className = "navbar-item" to='/foundform'>Foundform</Link>
                <Link onClick = {this.toggleBurget} className = "navbar-item" to='/lostform'>Lostform</Link>
                <Link to = "/" onClick = {() => this.logout.bind(this)} className = "navbar-item">Logout</Link>
              </span>
              : [
                <Link onClick = {this.toggleBurger} className = "navbar-item is-large" to='/login'>Login</Link>,
                <Link onClick = {this.toggleBurger} className = "navbar-item" to='/register'>Register</Link>,
              ]
            }
          </div>
        </div>
      </div>
    </nav>
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    logout: () => dispatch(logoutUser())
  }
}

const mapStateToProps = ({auth}) => {
  return {auth}
}

export default connect(mapStateToProps, mapDispatchToProps)(Nav)

Я не понимаю, почему вы используете как состояние компонента, так и состояние редукции, чтобы отслеживать, вышел ли пользователь из системы. В любом случае, вы передаете dispatch в mapDispatchToProps и должны обернуть ваши функции, которые вы определяете внутри mapDispatchToProps, с помощью dispatch(), чтобы они были отправлены диспетчеру:

const mapDispatchToProps = dispatch => ({
  logout: () => dispatch(logoutUser())
})

Использование такого шаблона позволит вам сконцентрировать все диспетчерские вызовы внутри mapDispatchToProps.

Полный редуктор (я инициализирую состояние как зарегистрированный, потому что у меня нет доступа к вашему модулю аутентификации, который фактически аутентифицирует пользователей):

const initialState = {
  isAuthenticated: true,
  isFetching: false,
}

const logoutReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'LOGOUT_REQUEST':
      return Object.assign({}, state, {
        isFetching: true,
      })
    case 'LOGOUT_SUCCESS':
      return Object.assign({}, state, {
        isFetching: false,
        isAuthenticated: false,
      })
    default:
      return state;
  }
}

export default logoutReducer;

Редуктор установлен в состоянии auth:

import { combineReducers } from 'redux';
import logoutReducer from './logoutReducer';

export const rootReducer = combineReducers({
  auth: logoutReducer,
});

Действия полного выхода:

const requestLogout = () => ({
  type: 'LOGOUT_REQUEST',
  isFetching: true,
  isAuthenticated: true
})

const receiveLogout = () => ({
  type: 'LOGOUT_SUCCESS',
  isFetching: false,
  isAuthenticated: false
})

export const logoutUser = () => {
  return dispatch => {
    document.location = "/#/"
    dispatch(requestLogout())
    //removeUser()
    dispatch(receiveLogout())
  }
}

Полный компонент:

import React from 'react'
import {connect} from 'react-redux'
import {Link} from 'react-router-dom'
import {logoutUser} from '../actions/logout'

class Nav extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      showBurger: true,
      loggedOut: false
    }
    this.toggleBurger = this.toggleBurger.bind(this)
    this.logout = this.logout.bind(this)
  }
  toggleBurger() {
    this.setState({showBurger: !this.state.showBurger})
  }

  logout () {
    console.info('logging out')
    this.props.logout()
    this.setState({loggedOut: true})
  }

  render() {
    //
    const {auth} = this.props
    const {loggedOut} = this.state
    console.info('is this logout?', this.logout)

    return <nav className='navbar'>
      <div className='container'>
        <div className='navbar-brand' style = {{
            height: '40px',
            width: '40px',
            background: 'red',
          }}>
          <span onClick = {this.toggleBurger}
            className = {
              `navbar-burger burger ${this.state.showBurger ? 'is-active': ''}`
            } data-target='navbarMenuHeroA'>
            <span></span>
            <span></span>
            <span></span>
          </span>
        </div>
        <div id='navbarMenuHeroA' 
          className = {
            `navbar-menu ${this.state.showBurger ? 'is-active' : ''}`
          }>
          <div className='navbar-end'>
            <Link onClick = {this.toggleBurger}
              className='navbar-item'
              to='/found'>Found</Link>
            <Link onClick = {this.toggleBurger}
              className='navbar-item'
              to='/lost'>Lost</Link>
            {auth.isAuthenticated
              ? <span>
                <Link onClick = {this.toggleBurger}
                  className='navbar-item'
                  to='/foundform'>Foundform</Link>
                <Link onClick = {this.toggleBurger}
                  className='navbar-item'
                  to='/lostform'>Lostform</Link>
                <Link onClick = {this.logout}
                  className='navbar-item'
                  to='/'>Logout</Link>
              </span>
              : [
                <Link onClick = {this.toggleBurger}
                  className='navbar-item is-large'
                  to='/login'>Login</Link>,
                <Link onClick = {this.toggleBurger}
                  className='navbar-item'
                  to='/register'>Register</Link>,
              ]
            }
          </div>
        </div>
      </div>
    </nav>
  }
}

const mapDispatchToProps = dispatch => ({
  logout: () => dispatch(logoutUser())
})

const mapStateToProps = state => ({
  auth: state.auth,
})

export default connect(mapStateToProps, mapDispatchToProps)(Nav)

Я думаю, вам нужно значительно упростить, прежде чем продолжить или задавать вопросы о StackOverflow. Создайте простое однокомпонентное приложение с одним div, которое позволяет пользователям щелкать для входа в систему и щелкать для выхода. Затем по очереди вводите элементы. Когда вы застряли, сократите приложение до его минимально жизнеспособного выражения проблемы и опубликуйте это как вопрос здесь, и люди будут рады помочь ...

Привет всем, спасибо за ответы, но я все равно получаю те же ошибки.

Jattsingh 08.06.2018 05:24

@Jattsingh, это ваше первое знакомство с React (или с React Router или Redux)? Этот код выглядит довольно запутанным; Я настоятельно рекомендую сначала попытаться создать более простой вариант использования, а затем использовать этот компонент аутентификации ...

duhaime 08.06.2018 13:05

@Jattsingh вы смотрели мой обновленный ответ? Попробуйте использовать create-react-app или какой-нибудь абсолютно минимальный шаблон и реализовать вышеизложенное, и вы увидите, что изменения работают ...

duhaime 09.06.2018 13:29

Спасибо за все ваши ответы, но, возможно, проблема в другом, я добавил еще код. Это был групповой проект, но я в основном работал над реакциями, а сокращение все еще для меня в новинку.

Jattsingh 13.06.2018 05:09

@Jattsingh, вы использовали приложение create-response-app и компоненты, которые я вставил выше? Если да, то с какими проблемами вы столкнулись? Если нет, я думаю, вам следует попробовать это, чтобы изолировать проблему, с которой вы сталкиваетесь ...

duhaime 13.06.2018 15:36

Это работает, спасибо вам большое. Должно быть, изначально была неправильна mapStateToProps. Ваше здоровье.

Jattsingh 14.06.2018 03:35

@Jattsingh ура! Я рада, что у тебя все получилось! Получайте удовольствие от изучения Redux. Учебники Egghead.io очень хороши, если вы еще не проверили их ...

duhaime 14.06.2018 03:36

@Jattsingh не стесняйтесь нажимать галочку рядом с этим ответом, чтобы люди могли видеть, что проблема решена!

duhaime 20.06.2018 12:30

Другие вопросы по теме