[英]Array gets undefined - React Redux
我是React和Redux的新手。 試圖理解基礎知識並做一些簡單的例子,但是我在這個問題上停留了超過一天,我找不到解決方法。 我想我的錯誤是愚蠢的錯誤。
問題是我無法打印用戶數組。 調試時,變量users會加載所有更正的ID和用戶,但是在執行<li key={id}>{name}</li>
三次之后,它返回到forEach並給了我這個例外: 未被捕獲TypeError:無法讀取未定義的屬性'forEach' ,其中用戶是未定義的。 而且我還得到對應於PropTypes的錯誤: 提供給HomePage的類型為array的無效prop用戶,預期對象
這是代碼:
存儲/配置Store.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers/index';
const initialState = {};
const middleware = [thunk];
const store = createStore(rootReducer, initialState, compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
));
export default store;
reducers / index.js
import { combineReducers } from 'redux';
import userReducer from './userReducer';
//import groupReducer from './groupReducer';
export default combineReducers({
user: userReducer
});
reducers / userReducer.js
import { GET_USERS, ADD_USER, DELETE_USER } from '../actions/types';
const initialState = {
users: [
{ id: 1, name: 'brunao'},
{ id: 2, name: 'flavio'},
{ id: 3, name: 'dudu'}
]
};
export default function(state = initialState, action) {
switch (action.type) {
case GET_USERS:
return [
...state
];
default:
return state;
}
}
動作/用戶Action.js
import { GET_USERS, ADD_USER, DELETE_USER } from './types';
export const getUsers = () => {
return {
type: GET_USERS
};
};
組件/HomePage.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getUsers } from '../actions/usersActions';
import PropTypes from 'prop-types';
class HomePage extends Component {
componentDidMount() {
this.props.getUsers();
}
render() {
const { users } = this.props.user;
return(
<div>
<h3>Users</h3>
<ul>
{users.forEach(({id, name}) => (
<li key={id}>{name}</li>
))}
</ul>
</div>
);
}
}
HomePage.propTypes = {
getUsers: PropTypes.func.isRequired,
user: PropTypes.object.isRequired
}
const mapStateToProps = (state) => ({
user: state.user
});
export default connect(mapStateToProps, { getUsers })(HomePage);
您在減速器中返回了錯誤的狀態。 您的相關代碼:
export default function(state = initialState, action) {
switch (action.type) {
case GET_USERS:
return [
...state
];
default:
return state;
}
}
在這里,狀態是一個對象,但是您要通過傳播將其以數組形式返回。 因此,您的狀態被破壞了。
像這樣嘗試:
case GET_USERS:
return state;
正如@Idan Dagan在他的回答中指出的那樣,實際上,我們不會在化簡器中改變狀態。 我剛剛提出了這個建議,因為您只是在玩耍學習Redux,我們將在這里返回原始狀態,僅此而已。 但是,這是一種返回狀態的合適且更好的方法:
case GET_USERS:
return { ...state };
這是一個工作代碼: https : //codesandbox.io/s/k5ymxwknpv
我也按照@Idan Dagan的建議再次更改了forEach
的map
。 我還沒意識到。 forEach
在這里不是合適的方法,因為它實際上不返回任何內容。 您想在React中映射數組並渲染它們。
另外,您的州名令人困惑:) user.users
,您可能認為更好的一個。
評論后編輯
您的GET_USERS動作實際上已被擊中,但您在代碼中檢查的是錯誤的。 您正在執行:
export default function(state = initialState, action) {
switch (action.type) {
case GET_USERS:
return Object.assign({}, state);
default:
return {
users: [
{ id: 1, name: "TEST" },
{ id: 2, name: "TEST1" },
{ id: 3, name: "TEST2" }
]
};
}
}
這里會發生什么? Redux的第一個動作是INIT
。 這是您狀態的初始化。 現在,由於沒有任何動作,減速器將達到默認情況並返回TEST。 現在,您的狀態成為該TEST數據。 然后,您的GET_USERS
被擊中,並且您返回一個新對象,該對象合並了處於測試狀態的狀態。 步驟如下:
First, state is the `initialState` -> `INIT` runs and hits the default case
State is now TEST one -> GET_USERS hit and returns the `state` which is TEST one
You see the TEST one.
您如何測試自己的行為? 只需將console.log
放入您的reducer中:
export default function(state = initialState, action) {
console.log("state",state);
console.log("action",action);
.....
並看到GET_USERS實際上被擊中了。 另一個選擇是代替返回帶有state
的合並對象,嘗試將其與initialState
合並,或者使用spread運算符通過使用initialState
返回一個新對象:
return return Object.assign({}, initialState);
要么
return {...initialState}
最后一個選項使您更加了解我的第一個解釋的工作原理。 嘗試為您的GET_USERS返回此代碼:
return {...state, users:[...state.users, {id:4, name: "foo"}]};
您將看到一個包含TEST數據的用戶列表,但最后一個將是您的foo
。 這說明了如果在默認情況下返回除state
任何內容,將如何initialState
。
最后的建議是,您可以使用Redux Dev Tools調試您的Redux開發。 它是一個很棒的工具,除了調試以外,還可以做更多的事情。 您可以輕松跟蹤Redux的所有操作。
我不確定您要如何處理新狀態。
但是您需要做一些更改:
export default function(state = initialState, action) { switch (action.type) { case GET_USERS: return Object.assign({}, state); default: return state; } }
如redux文檔中所述 :
我們不改變國家 。 我們使用Object.assign()
創建一個副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.