如何使用react-redux调试action.type问题,单操作类型单减速器,但无法识别类型

时间:2019-04-09 21:04:09

标签: reactjs redux react-redux

我正在设置一个非常简单的react-redux应用程序,此刻我只有一个动作类型和一个reducer,所以使用switch或Combinereduces并不是问题,因为只有一个选项。在我的reducer中,我有一个布尔语句说

if(action.type === ADD_ITEM)然后返回(归约代码)

然后在我的商店中调用reducer函数。当我测试我的应用程序时,状态没有更新,并且通过添加一些console.logs以查看问题出在哪里,我意识到未调用reducer代码,因为action.type === ADD_ITEM返回为false。

我尝试在控制台上记录action.type,但是我只得到了默认的{type: @@redux/INITp.m.x.p.a.c},它没有告诉我为什么它不读取action.type为ADD_ITEM。

顺便说一句:操作类型在import { ADD_ITEM } from "../constants/action-types";中传递,并且操作类型包含此export const ADD_ITEM = "ADD_ITEM";,因为我更喜欢为此使用常量而不是字符串。

我知道action.type不会被称为“ ADD_ITEM”,但是我不知道为什么,而且我要检查的地方也用光了。我在堆栈溢出时浏览了其他与此类似的问题,但是它们都涉及使用switch来设置多种动作类型,或者使用组合减速器,或者将action.type设为未定义。我只有一个动作和一个reducer,action.type不会像未定义的那样返回,而不会像我设置为调用reducer函数的动作类型一样返回。另外,这是我第一次使用redux,请保持友善。

动作:

import { ADD_ITEM } from "../constants/action-types";

export function addArticle(payload){
    return { type: ADD_ITEM, payload };
};

action-types.js:export const ADD_ITEM = "ADD_ITEM";

减速器:

import { ADD_ITEM } from "../constants/action-types";

const initialState = {
    articles: []
};

function rootReducer(state = initialState, action){
    if(action.type === ADD_ITEM){
        console.log("yes");
        return Object.assign({}, state, {
            articles: state.articles.concat(action.payload)
        });
    }
    console.log("no");
    return state;
};

export default rootReducer; 

商店:


import { createStore } from "redux";
import rootReducer from '../reducers/index';

const store = createStore(rootReducer);

export default store;

应该更新的表单组件,并使用表单输入中的文章标题调用调度:

import React, { Component } from "react";
import { connect } from "react-redux";
import uuidv1 from "uuid";
import { addArticle } from "../actions/index";

function mapDispatchToProps(dispatch){
    return {
        addArticle: article => dispatch(addArticle(article))
    };
}

class ConnectedForm extends Component {
    constructor() {
        super();

        this.state = {
            title: ""
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleChange.bind(this);
    }

    handleChange(event) {
        this.setState({ [event.target.id]: event.target.value });
    }

    handleSubmit(event) {
        event.preventDefault();
        const { title } = this.state;
        const id = uuidv1();
        this.props.addArticle({ title, id });
        this.setState({ title: "" });
    }

    render() {
        const { title } = this.state;

        return (
            <form onSubmit={this.handleSubmit}>
                <div className="form-group">
                <label htmlFor="title">Title</label>
                <input
                    type="text"
                    className="form-control"
                    id="title"
                    value={title}
                    onChange={this.handleChange}
                />
                </div>
                <button type="submit" className="btn btn-success">
                SAVE
                </button>
            </form>
        );
    }
}

const Form = connect(null, mapDispatchToProps)(ConnectedForm);

export default Form;

添加的文章应呈现的列表:

import React from "react";
import { connect } from "react-redux";

const mapStateToProps = state => {
    return { articles: state.articles };
};

const ConnectedList = ({ articles }) => (
    <ul className="list-group list-group-flush">
    {articles.map(el => (
        <li className="list-group-item" key={el.id}>
        {el.title}
        </li>
    ))}
    </ul>
);

const List = connect(mapStateToProps)(ConnectedList);

export default List;

index.js,我在其中设置了提供程序:


import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import store from "./store/index";
import App from './components/App.jsx';

render(
<Provider store={store}>
<App />
</Provider>
, document.getElementById('root')
);

与之配套的应用程序:

import React, { Component } from 'react';
import List from "./List";
import Form from "./Form";

class App extends Component {
  render() {
    return (
      <div className="row mt-5">
        <div className="col-md-4 offset-md-1">
        <h2>Article List</h2>
        <List />
        </div> 
        <div className="col-md-4 offset-md-1">
        <h2>Add a new article</h2>
        <Form />
        </div>
      </div>
    );
  }
}

export default App;

我希望当我输入标题并提交表格时,它应该使用新的“文章”调用dispatch,将其添加到状态中,然后将其打印为列表组件的一部分。

但是,归约器实际上将新输入添加到初始状态的部分没有运行,因为action.type === ADD_ITEM返回的是false。

注意:当我仅在console.testing.js文件中使用以下命令运行它时:

import store from "../js/store/index";
import { addArticle } from "../js/actions/index";
window.store = store;
window.addArticle = addArticle;

我可以在控制台中运行store.getState(),它将返回空数组,然后可以运行

store.dispatch( addArticle({ title: 'What is happening?', id: 1 }) )

,它将把它添加到数组中。

该逻辑起作用了,但是我想是因为当我使用表单组件运行它而不直接调用store.dispatch时,它依赖于action.type === ADD_ITEM语句,因此实际上没有其他逻辑被调用

我只是不知道为什么action.type不被读取为ADD_ITEM,因为在我的action.js文件中,我定义了类型为ADD_ITEM的addArticle函数

任何帮助将不胜感激

编辑:

我忘了提一下,如果我console.log(addArticle())在减速器中返回它

{type: "ADD_ARTICLE", payload: undefined}
payload: undefined
type: "ADD_ARTICLE"
__proto__: Object

所以addArticle()的类型确实为“ ADD_ARTICLE”,但我传递给rootReducer的操作却没有。.

2 个答案:

答案 0 :(得分:0)

当我绑定我的处理程序时结果

 this.handleChange = this.handleChange.bind(this);
 this.handleSubmit = this.handleChange.bind(this);

代替

 this.handleChange = this.handleChange.bind(this);
 this.handleSubmit = this.handleSubmit.bind(this);

因此未调用handleSubmit。我觉得这很简单

答案 1 :(得分:0)

我建议使用此浏览器扩展https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd 它可以让您查看该动作是否被触发,该动作的有效载荷是什么以及对应用程序状态产生了什么影响。非常适合调试!