Не удается получить доступ к `action.type`, но можно получить доступ к `action` на редюсере

Я могу получить доступ только к action, но не к action.type на моем редукторе. Я попытался выполнить console.info(action.type), но это дало неопределенное значение.


export const INPUT_EMAIL = 'INPUT_EMAIL'
export const INPUT_PASSWORD = 'INPUT_PASSWORD'

export function inputEmail(email) {
    return {
        type: INPUT_EMAIL,
        email
    }
}

export function inputPassword(password) {
    return {
        type: INPUT_PASSWORD,
        password,
    }
}

// import { INPUT_EMAIL, INPUT_PASSWORD } from './actions';

const initialState = {
    email: '',
    password: '',
}

function loginReducers(state = initialState, action: Object) {
    console.info('zzZaction', action); <-- just found out it's existing 
    if (typeof state === 'undefined'){
        return initialState
    }
    // switch (action.type) {
    //     case INPUT_EMAIL: 
    //         return Object.assign({},state, {
    //             email: action.email
    //         })
    //     case INPUT_PASSWORD: 
    //     return Object.assign({}, state, {
    //         password: action.password,
    //     })
    //     default:
    //         return state
    // }
    return state
}


export default loginReducers;
//MAINPAGE

import React from 'react';
import { connect } from 'react-redux';
import './Dashboard.css';
import { inputEmail, inputPassword } from './redux/actions';
import Logo from './assets/login-logo.jpg';


class LoginForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: '',
        };
        this.store = this.props.store;

        this.handleEmailChange = this.handleEmailChange.bind(this);
        this.handlePasswordChange = this.handlePasswordChange.bind(this);
        // this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleEmailChange(event) { 
        this.setState({ email: event.target.value});
        this.props.inputEmail(this.state.email);       
    }

    handlePasswordChange(event) {
        this.setState({ password: event.target.value });
        this.props.inputPassword(this.state.password);
    }


    render() {
        return (
            <div className = "Dashboard">
                <div className = "Dashboard-header">
                    <img className = "Dashboard-logo" src = {Logo} alt = {'login-logo'} />
                    <h1 className = "">Login Page</h1>
                </div>
                <div className = "Dashboard-content">
                    <form className = "Dashboard-loginContainer" onSubmit = {this.handleSubmit}>
                        <label>
                            Email:
                    <input type = "email" value = {this.state.email} name = "email" onChange = {this.handleEmailChange} />
                        </label>
                        <label>
                            Password:
                    <input type = "password" value = {this.state.password} onChange = {this.handlePasswordChange} />
                        </label>
                        <input type = "submit" value = "Log-In" />
                    </form>
                </div>
            </div>
        );
    }
}

// const mapStateToProps = (state) => {

//     return {
//         email: state.email,
//         password: state.password,
//     }
// }


const mapDispatchToProps = dispatch => {
    return {
        inputEmail: (email: string) => dispatch(inputEmail(email)),
        inputPassword: (password: string) => dispatch(inputPassword(password)),
    }
};


export default connect(null, mapDispatchToProps)(LoginForm);

Что дает console.info(action)?

Rajendran Nadar 21.05.2019 07:48

это дает мне такой результат: zzZaction {type: "INPUT_EMAIL", email: "dg"}, за которым следует zzZaction undefined

Gabrielle Durano 21.05.2019 07:49

Не используйте setState внутри обработчика onChange, если email и password передаются через mapStateToProps и обновляются через диспетчеризацию.

Joseph D. 21.05.2019 07:52

Вы используете TypeScript или JavaScript?

Fyodor 21.05.2019 07:53

@Фёдор Джаваскрипт

Gabrielle Durano 21.05.2019 07:57

Как это работает? function loginReducers(state = initialState, action: Object) Эта сигнатура функции недействительна в JS.

Fyodor 21.05.2019 07:59

Сгенерируйте репродукцию в stackblitz, будет проще отлаживать.

Rajendran Nadar 21.05.2019 08:12

@RajendranNadar stackblitz.com/edit/react-plq56z вот оно

Gabrielle Durano 21.05.2019 08:30

@GabrielleDurano только что написала вам ответ! Дайте мне знать, если это поможет :)

Chris Ngo 21.05.2019 09:55
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
9
417
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Проблема здесь:

store.subscribe((loginReducers));

Вместо того, чтобы распечатывать свое состояние редуктора, вы выполняете функцию редуктора. Subscribe будет срабатывать каждый раз, когда в вашем магазине происходят изменения. На самом деле действие проходит с первого раза, но так как вы вызываете loginReducers внутри subscribe, оно запускает функцию редюсера и возвращает ошибку "cannot get type of undefined."

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

Это объясняет, почему вы можете напечатать действие в первомconsole.info(), но затем получить неопределенное значение во втором. Второй console.info() возникает из-за попытки подписки выполнить loginReducers, когда в нее не было передано никаких действий, возвращая неопределенное значение.

Что вы хотите, так это:

store.subscribe(() => console.info(store.getState()));

Вот ваша обновленная песочница для справки: https://stackblitz.com/edit/react-zjywof

Теперь у вас не должно быть ошибок при доступе к типу действия.

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