这是来自Dave Ceddia的Redux课程的一个教程作业,我试图显示包含对象数组的初始状态,但是它只是返回未定义的内容而不显示任何内容。我是React的新手,在获取1)我的按钮以显示状态和2)默认状态为最初出现时遇到了麻烦。
我试图将组件Buttons
作为类和常量。
我也尝试在我的减速器的initialReducer
中声明我的default: return state;
。我还对调度操作尝试了不同的语法,但减速器似乎没有任何作用。
index.js
import React, { Fragment } from "react";
import ReactDOM from "react-dom";
import { getAllItems, addEventToBeginning, addEventToEnd } from "./actions";
import { connect, Provider } from "react-redux";
import { store } from "./reducers";
const Buttons = ({
state,
getAllItems,
addEventToBeginning,
addEventToEnd
}) => (
<React.Fragment>
<ul>{state ? state.actions.map(item => <li>{item}</li>) : []}</ul>
<button onClick={getAllItems}> Display items </button>
<button onClick={addEventToBeginning}> addEventToBeginning </button>
<button onClick={addEventToEnd}> addEventToEnd </button>
</React.Fragment>
);
const mapDispatchToProps = { getAllItems, addEventToBeginning, addEventToEnd };
const mapStateToProps = state => ({
actions: state.actions,
sum: state.sum
});
connect(
mapStateToProps,
mapDispatchToProps
)(Buttons);
reducers.js
const initialState = {
actions: [
{ id: 0, type: "SALE", value: 3.99 },
{ id: 1, type: "REFUND", value: -1.99 },
{ id: 2, type: "SALE", value: 17.49 }
],
sum: 0
};
const newUnit = { id: Math.random * 10, type: "SALE", value: Math.random * 25 };
function eventReducer(state = initialState, action) {
switch (action.type) {
case ADD_EVENT_TO_BEGINNING:
const copy = { ...state };
copy.actions.unshift(newUnit);
return copy;
case ADD_EVENT_TO_END:
const copy2 = { ...state };
copy2.actions.unshift(newUnit);
return copy2;
切出干净
case GET_ITEMS:
return {
...state,
actions: state.actions,
sum: state.sum
};
default:
return state;
}
}
export const store = createStore(eventReducer);
actions.js示例(它们都遵循相同的格式)
export const ADD_EVENT_TO_BEGINNING = "ADD_EVENT_TO_BEGINNING";
export function addEventToBeginning() {
return dispatch => {
dispatch({
type: ADD_EVENT_TO_BEGINNING
});
};
}
更新:
谢谢@ ravibagul91和@Yurui_Zhang,我将除getAllItems之外的所有内容都剪掉了,并将状态更改为:
const initialState = {
itemsById: [
{ id: 0, type: "SALE", value: 3.99 },
{ id: 1, type: "REFUND", value: -1.99 },
{ id: 2, type: "SALE", value: 17.49 }
]
};
class Form extends React.Component {
render() {
return (
<div>
{this.props.itemsById
? this.props.itemsById.map(item => (
<li>
{item.id} {item.type} {item.value}
</li>
))
: []}
<button onClick={this.getAllItems}> Display items </button>
</div>
);
}
}
const mapDispatchToProps = { getAllItems };
function mapStateToProps(state) {
return {
itemsById: state.itemsById
};
}
export function getAllItems() {
return dispatch => ({
type: "GET_ITEMS"
});
}
答案 0 :(得分:0)
您的代码有多个问题:
const mapStateToProps = state => ({
actions: state.actions,
sum: state.sum
});
这里您已将redux状态字段映射到道具actions
和sum
-您的组件将不会收到state
道具,而是它将收到actions
和{{ 1}}。
所以您的组件确实应该是:
sum
您的const Button = ({
actions,
sum,
}) => (
<>
<ul>{actions && actions.map(item => <li>{item}</li>)}</ul>
</>
);
函数未正确定义。应该是这样的:
mapDispatchToProps
您的reducer似乎也没有正确定义,但是您应该尝试解决我首先提到的问题:)
在学习react / redux时,不要一劳永逸。我建议您回顾一下基础知识(数据流如何工作,如何将状态从redux存储映射到您的组件,什么是动作创建者等)。
答案 1 :(得分:0)
在破坏道具时,
// ideally you don't want the function names in your component to be the same as the ones you imported so I'm renaming it here:
import { getAllItems as getAllItemsAction } from "./actions";
// you need to actually `dispatch` the action
const mapDispatchToProps = (dispatch) => ({
getAllItems: () => dispatch(getAllItemsAction()),
});
您无权访问const Buttons = ({
state,
getAllItems,
addEventToBeginning,
addEventToEnd
}) => ( ...
,而是需要直接使用state
和actions
,
sum
您的mapDispatchToProps
应该是
const Buttons = ({
actions, // get the actions directly
sum, // get the sum directly
getAllItems,
addEventToBeginning,
addEventToEnd
}) => (
<React.Fragment>
//You cannot print object directly, need to print some values like item.type / item.value
<ul>{actions && actions.length && actions.map(item => <li>{item.type} {item.value}</li>)}</ul>
<button onClick={getAllItems}> Display items </button>
<button onClick={addEventToBeginning}> addEventToBeginning </button>
<button onClick={addEventToEnd}> addEventToEnd </button>
</React.Fragment>
);
或者您可以使用const mapDispatchToProps = dispatch => {
return {
// dispatching actions returned by action creators
getAllItems : () => dispatch(getAllItems()),
addEventToBeginning : () => dispatch(addEventToBeginning()),
addEventToEnd : () => dispatch(addEventToEnd())
}
}
,
bindActionCreators
在import { bindActionCreators } from 'redux'
function mapDispatchToProps(dispatch) {
return {
dispatch,
...bindActionCreators({ getAllItems, addEventToBeginning, addEventToEnd }, dispatch)
}
}
中,reducer
应该将元素添加到数组的末尾,但是您将使用ADD_EVENT_TO_END
在开头重新添加元素。您应该使用unshift
,它将在数组的末尾添加元素,
push
您的case ADD_EVENT_TO_END:
const copy2 = { ...state };
copy2.actions.push(newUnit); //Add element at the end
return copy2;
也应该如此简单
GET_ITEMS