我已经通过redux中的数据进行了规范化,但是现在抓取并显示在前端会导致问题。
我已经尝试修复了几天,我尝试了我认为最明显的this.props ....,但是我显然缺少了一些东西。正在使用曼宁关于Redux的最新书籍《行动中的Redux》,到目前为止对我来说都是不错的指南。
我正试图分解数据,因此树将具有业务(仪表板)和业务位置(另一页)。
在我的Redux DevTools控制台中,操作树如下所示:
type: 'RECEIVE_ENTITIES'
payload
entities
business_locations
- 652 {id: 652, business_id: 452...}
business
- 452 {id: 452}
result: 452
我的businessReducer:
import {
RECEIVE_ENTITIES,
FETCH_BUSINESS_STARTED,
FETCH_BUSINESS_SUCCESS,
SET_CURRENT_BUSINESS_ID,
} from '../../actions/types';
const initialBusinessState = {
items: [],
isLoading: false,
error: null,
};
export const getBusinesses = state => {
return Object.keys(state.business.items).map(id => {
return state.business.items[id];
});
};
export default function businesses(state = initialBusinessState, action) {
switch (action.type) {
case RECEIVE_ENTITIES: {
const { entities } = action.payload;
if (entities && entities.businesses) {
return {
...state,
isLoading: false,
items: entities.businesses,
};
}
return state;
}
case FETCH_BUSINESS_STARTED: {
return {
...state,
isLoading: true,
};
}
case FETCH_BUSINESS_SUCCESS: {
return {
...state,
isLoading: true,
items: action.payload.businesses,
};
}
default: {
return state;
}
}
}
export function setCurrentBusinessId(id) {
return {
type: SET_CURRENT_BUSINESS_ID,
payload: {
id,
},
};
}
我的businessActions;
import { normalize } from 'normalizr';
import {
FETCH_BUSINESS_STARTED,
FETCH_BUSINESS_ERROR,
RECEIVE_ENTITIES,
SET_CURRENT_BUSINESS_ID,
} from './../types';
import * as schema from '../schema';
import * as api from '../../api';
function fetchBusinessStarted() {
return {
type: FETCH_BUSINESS_STARTED,
};
}
function fetchBusinessFailed(err) {
return {
type: FETCH_BUSINESS_ERROR,
payload: {
err,
},
};
}
function receiveEntities(entities) {
return {
type: RECEIVE_ENTITIES,
payload: entities,
};
}
export function setCurrentBusinessId(id) {
return {
type: SET_CURRENT_BUSINESS_ID,
payload: {
id,
},
};
}
export function fetchBusinesses() {
return (dispatch, getState) => {
dispatch(fetchBusinessStarted());
return api
.fetchBusinesses()
.then(resp => {
const businesses = resp.data;
const normalizedData = normalize(businesses, schema.businessSchema);
console.log('normalizedData', normalizedData);
dispatch(receiveEntities(normalizedData));
if (!getState().page.currentBusinessId) {
const defaultBusinessId = sessionStorage.getItem('business_id');
dispatch(setCurrentBusinessId(defaultBusinessId));
}
})
.catch(err => {
console.log(err);
fetchBusinessFailed(err);
});
};
}
我的pageReducer
import { SET_CURRENT_BUSINESS_ID } from '../../actions/types';
const InitialPageState = {
currentBusinessId: null,
};
export default function page(state = InitialPageState, action) {
switch (action.type) {
case SET_CURRENT_BUSINESS_ID: {
return {
...state,
currentBusinessId: action.payload.id,
};
}
default: {
return state;
}
}
}
我的模式
import { schema } from 'normalizr';
const businessLocationSchema = new schema.Entity('business_locations');
const businessSchema = new schema.Entity('business', {
business_locations: [businessLocationSchema],
});
export { businessSchema };
rootReducer
const rootReducer = (state = {}, action) => {
return {
page: pageReducer(state.page, action),
business: businessReducer(state.businesses, action),
businessLocation: businessLocationsReducer(state.businessLocations,
action),
form: formReducer,
};
};
前端:
class Dashboard extends React.Component {
componentDidMount() {
this.props.dispatch(fetchBusinesses());
}
render() {
if (this.props.isLoading) {
return (
<SpinContainer>
<Spin size="large" />
</SpinContainer>
);
}
console.log(this.props);
return (
<Wrapper>
<Card bordered={false}>
<Maps
zoom={16}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `30vh` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
<p>{this.props.business.website}</p>
<p>{this.props.business.businessName}</p>
</Card>
<Link to="/locations">
<Card bordered={false}>
<h1>****</h1>
</Card>
</Link>
<Link to="stamp-cards">
<Card bordered={false}>
<h1>*****</h1>
</Card>
</Link>
<Card bordered={false}>
<h1>*****</h1>
</Card>
</Wrapper>
);
}
}
function mapStateToProps(state) {
const { isLoading, business } = state.business;
return {
business: getBusinesses(state),
isLoading,
};
}
export default connect(mapStateToProps)(Dashboard);