我正在设置一个非常简单的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的操作却没有。.
答案 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 它可以让您查看该动作是否被触发,该动作的有效载荷是什么以及对应用程序状态产生了什么影响。非常适合调试!