来自Redux的规范化数据未在前端显示(使用react)

时间:2018-06-20 17:38:04

标签: reactjs redux react-redux

我已经通过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);

0 个答案:

没有答案