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

Posted

技术标签:

【中文标题】如何使用 react-redux 调试 action.type 问题,单动作类型单减速器,但无法识别类型【英文标题】:How to debug action.type issue with react-redux, single action type single reducer but it's not recognizing the type 【发布时间】:2019-08-31 05:56:52 【问题描述】:

我正在设置一个非常简单的 react-redux 应用程序,我目前只有一个动作类型和一个减速器,所以使用 switch 或组合减速器不是问题,因为只有一个选项。在我的减速器中,我有一个布尔语句说

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

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

我尝试在控制台记录 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 设置为未定义。我只有一个动作和一个减速器,并且 action.type 并没有像未定义一样返回,它只是没有作为我设置为调用减速器函数的动作类型返回。另外,这是我第一次使用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 将其添加到状态,然后将其作为列表组件的一部分打印。

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

注意:当我在控制台中从 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 的操作没有..

【问题讨论】:

【参考方案1】:

我推荐使用这个浏览器扩展https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd 它将允许您查看操作是否被触发、操作的有效负载是什么以及它对应用程序的状态有什么影响。非常适合调试!

【讨论】:

【参考方案2】:

原来当我绑定我的处理程序时

 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。我有一种感觉,就像这样简单

【讨论】:

以上是关于如何使用 react-redux 调试 action.type 问题,单动作类型单减速器,但无法识别类型的主要内容,如果未能解决你的问题,请参考以下文章

React-Redux 知识点 及 实现数据共享案例

Lerna,React-Redux Web应用程序使用可视代码编辑器调试器调试Chrome插件

Reactredux - 三大核心概念 - action - reducer - store - 异步编程 - react-redux - 调试工具 - 纯函数 - 高阶函数

如何将更改的状态发送到 react-native 中的组件?

如何使用 react-redux 钩子测试组件?

如何通过 react-redux 使用 refs 进行反应,withRouter?