我无法理解redux状态如何基于操作有效负载和reducer函数分配状态对象。以下是我的示例代码。我在不同部分做了笔记并提出了问题,但总的来说,这是我的问题:
state.competitions
而不是state.items
将状态映射到我的CompetitionList道具?我的操作代码:
function getAll() {
return dispatch => {
dispatch(request());
myService.getAll()
.then(
competitions => dispatch(success(competitions)),
error => dispatch(failure(error))
);
};
function request() { return { type: constants.GETALL_REQUEST } }
function success(competitions) { return {type: constants.GETALL_SUCCESS, competitions}}
function failure(error) { return {type: constants.GETALL_FAILURE, error}}
}
我的减速器代码:
import { constants } from '../_constants';
const initialState = {items: [], loading: false, selected: null}
export function competitions(state = initialState, action) {
switch (action.type) {
case constants.GETALL_REQUEST:
return {
loading: true
};
case constants.GETALL_SUCCESS:
console.log("the action value: ", action)
return {
items: action.competitions
};
case constants.GETALL_FAILURE:
console.log("the failed action value: ", action)
return {
error: action.error
};
default:
return state
}
}
在我的组件中,有一个mapStateToProp函数,该函数传递给我进行连接。第一个不起作用。为什么?
选项1-不起作用
function mapStateToProps(state) {
const { selected, ...competitions } = state.competitions;
return {
competitionList: competitions,
isLoading: state.loading
};
}
export default connect(mapStateToProps)(Dashboard);
此方法有效,但我希望CompetitionList变量具有返回的项目数组而不是整个状态对象,因此我尝试执行类似competition: state.competitions.items
的操作,但是会引发错误。
选项2-部分起作用(我只想分配比赛项目)
const mapStateToProps = (state) => ({
competitionList: state.competitions,
isLoading: state.loading
});
export default connect(mapStateToProps)(Dashboard);
我不能做
const { competitionList } = this.props;
{competitionList.map(competition =>
<tr key={competition.competitionId}>
<td>{competition.competitionName}</td>
</tr>
)}
我必须做:
const { competitionList } = this.props;
{competitionList.items.map(competition =>
<tr key={competition.competitionId}>
<td>{competition.competitionName}</td>
</tr>
)}
答案 0 :(得分:2)
我认为您缺少的一点是当您组合减速器时,每个减速器都会有一个钥匙,因为它们是对象。
在组合减速器的文件中,您可能会有类似的内容:
import { combineReducers } from 'redux'
import todos from './todos'
import competitions from './competitions'
export default combineReducers({
todos,
competitions
})
之后,您的状态将如下所示:
{
todos:{},
competitions:{
items: [],
loading: false,
selected: null
}
}
解释说,我认为一切都会变得更容易。
选项1-不起作用:它不起作用,因为您在competitions
状态内没有competitions
属性。即使有,也不应在其之前使用...
。如果您将competitions
的{{1}}替换为items
,因为items
处于competitions
状态之内:
function mapStateToProps(state) {
const { selected, items } = state.competitions;
return {
competitionList: items,
isLoading: state.loading
};
}
export default connect(mapStateToProps)(Dashboard);
或者我们可以改进它,使其更短:
function mapStateToProps(state) {
const { selected, items } = state.competitions;
return {
items,
selected
isLoading: state.loading
};
}
export default connect(mapStateToProps)(Dashboard);
通过这种方式,您可以使用代码的这一部分:
const { items } = this.props;
{items.map(competition =>
<tr key={competition.competitionId}>
<td>{competition.competitionName}</td>
</tr>
)}
我想指出的另一点是,您的isLoading
变量可能也不起作用,因为您正试图直接从状态而不是状态下的reducer读取它。
已编辑:我错过了另一点。减速器总是必须返回整个状态,而不仅仅是它的一个属性。
import { constants } from '../_constants';
const initialState = {items: [], loading: false, selected: null, error: null}
export function competitions(state = initialState, action) {
switch (action.type) {
case constants.GETALL_REQUEST:
/*return {
loading: true
};*/
//returning that I will overwrite your competition state with this object.
// this will keep all the competition state and will gerenate a new object changing only the loading attribute
return {
...state,
loading:true
}
case constants.GETALL_SUCCESS:
console.log("the action value: ", action)
return {
...state,
items: action.competitions
};
case constants.GETALL_FAILURE:
console.log("the failed action value: ", action)
return {
...state,
error: action.error
};
default:
return state
}
}