Не удается получить доступ к данным в моем хранилище redux react

#reactjs #redux

#reactjs #redux

Вопрос:

У меня есть компонент, который я пытаюсь получить доступ к данным из моего хранилища redux. С помощью своих инструментов разработки я могу видеть, что данные заполняются в хранилище redux. Однако, когда я пытаюсь утешить.запишите эти данные, чтобы просмотреть данные, прежде чем я внедрю их в свой компонент, я становлюсь неопределенным.

Вот мой компонент react.

 import React, { Fragment, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Table } from 'react-bootstrap';
import Moment from 'react-moment';
import Button from '../components/Button';
import ActivitySummary from '../components/ActivitySummary';

import { projectsInfoDetails } from '../actions/projectInfoActions';
import { projectContacts } from '../actions/projectContactActions';

import SectionHeader from '../components/SectionHeader';
import Loader from '../components/Loader';
import Message from '../components/Message';

const ProjectScreen = ({ match }) => {
  const dispatch = useDispatch();

  const projectInfoDetails = useSelector(state => state.projectInfoDetails);
  const { loading, error, projects } = projectInfoDetails;

  const contactDetails = useSelector(state => state.contactDetails);
  const { projectContactDetails } = contactDetails;

  useEffect(() => {
    dispatch(projectsInfoDetails(match.params.id));
    dispatch(projectContacts(match.params.id));
  }, [dispatch, match]);

  console.log(projectContactDetails);

  return (
    <Fragment>
      <div>
        <SectionHeader sectionName='Project' />
        <Button buttonName='Edit Project' />
      </div>
      {loading ? (
        <Loader />
      ) : error ? (
        <Message variant='danger'>{error}</Message>
      ) : (
        <div style={{ backgroundColor: '#F8F8F8' }}>
          <Table className='borderless'>
            <tbody>
              <tr>
                <td>
                  <strong>Name: </strong>
                  {projects.name}
                </td>
                <td>
                  <strong>Status: </strong>
                  {projects.status}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>State: </strong>
                  {projects.state}
                </td>
                <td>
                  <strong>County: </strong>
                  {projects.county}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Congressional District: </strong>
                  {projects.district}
                </td>
                <td>
                  <strong>Type: </strong>
                  {projects.type}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Funding Source: </strong>
                  <br />
                  {`${projects.fundingSource} ${projects.fundingSourceName}`}
                </td>
                <td>
                  <strong>Funding Source Goal: </strong>
                  <br />
                  {projects.fundingSourceGoal}
                </td>
                <td>
                  <strong>Start Date: </strong>
                  <br />
                  <Moment format='MM/DD/YYYY'>{projects.startDate}</Moment>
                </td>
                <td>
                  <strong>End Date: </strong>
                  <br />
                  {projects.endDate === null ? (
                    ''
                  ) : (
                    <Moment format='MM/DD/YYYY'>{projects.endDate}</Moment>
                  )}
                </td>
                <td>
                  <strong>Funding Percent: </strong>
                  <br />
                  {projects.fundingPercent}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Contact: </strong>
                  {projects.contact}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Start Date: </strong>
                  <Moment format='MM/DD/YYYY'>
                    {projects.projectStartDate}
                  </Moment>
                </td>
                <td>
                  <strong>End Date: </strong>
                  {projects.projectEndDate === null ? (
                    ''
                  ) : (
                    <Moment format='MM/DD/YYYY'>
                      {projects.projectEndDate}
                    </Moment>
                  )}
                </td>
              </tr>
              <tr>
                <td colSpan='5'>
                  <strong>Goals and Objectives: </strong>
                  {projects.goalsAndObjectives}
                </td>
              </tr>
              <tr>
                <td colSpan='5'>
                  <strong>Success Description: </strong>
                  {projects.successDescription}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Accountable Staff</strong>
                  {projects.accountableStaff amp;amp;
                    projects.accountableStaff.map(data => (
                      <tr key={data._id}>
                        {data.lastName}, {data.firstName}
                      </tr>
                    ))}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>Project ID: </strong>
                  {projects.projectId}
                </td>
              </tr>
            </tbody>
          </Table>
        </div>
      )}

      <ActivitySummary />
    </Fragment>
  );
};

export default ProjectScreen;
 

Вот мой редуктор:

 import {
  PROJECT_CONTACT_REQUEST,
  PROJECT_CONTACT_SUCCESS,
  PROJECT_CONTACT_FAIL
} from '../constants/projectConstants';

export const projectContactReducer = (
  state = { projectContact: [] },
  action
) => {
  switch (action.type) {
    case PROJECT_CONTACT_REQUEST:
      return { loading: true, projectContact: [] };
    case PROJECT_CONTACT_SUCCESS:
      return { loading: false, projectContact: action.payload };
    case PROJECT_CONTACT_FAIL:
      return { loading: false, error: action.payload };
    default:
      return state;
  }
};
 

и, наконец, мой вызов действия:

 import axios from 'axios';
import {
  PROJECT_CONTACT_REQUEST,
  PROJECT_CONTACT_SUCCESS,
  PROJECT_CONTACT_FAIL
} from '../constants/projectConstants';

export const projectContacts = id => async dispatch => {
  try {
    dispatch({ type: PROJECT_CONTACT_REQUEST });

    const { data } = await axios.get(`/api/projects/${id}/projectscontact`);
    dispatch({
      type: PROJECT_CONTACT_SUCCESS,
      payload: data
    });
  } catch (error) {
    dispatch({
      type: PROJECT_CONTACT_FAIL,
      payload:
        error.response amp;amp; error.response.data.message
          ? error.response.data.message
          : error.message
    });
  }
};
 

Вот как выглядит ответ от сервера в моих инструментах разработки:

ответ dev tools

я предполагаю, что это как-то связано с данными, которые не заполняются перед console.log, но, похоже, не могут получить доступ к данным.

Спасибо

TL

мой файл combine reducers:

 import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';

import { projectDetailsReducer } from './reducers/projectReducer';
import { pageReducer } from './reducers/pageReducer';
import { projectInfoReducer } from './reducers/projectInfoReducer';
import { fundingSourceReducer } from './reducers/fundingSourcesReducer';
import { fundSourceReducer } from './reducers/fundingSourceReducer';
import { contactsReducer } from './reducers/contactsReducer';
import { contactReducer } from './reducers/contactReducer';
import { projectContactReducer } from './reducers/projectContactReducer';

const reducer = combineReducers({
  projectDetails: projectDetailsReducer,
  projectInfoDetails: projectInfoReducer,
  pageDetails: pageReducer,
  fundingSourceDetails: fundingSourceReducer,
  fundSourceDetails: fundSourceReducer,
  contactsDetails: contactsReducer,
  contactDetails: contactReducer,
  projectContactDetails: projectContactReducer
});

const initialState = {};

const middleware = [thunk];

const store = createStore(
  reducer,
  initialState,
  composeWithDevTools(applyMiddleware(...middleware))
);

export default store;
 

Комментарии:

1. Покажите, пожалуйста, код, в котором вы комбинируете редукторы

2. Что он регистрирует, когда вы делаете const contactDetails = useSelector(state => console.log('state is:',JSON.stringify(state,undefined,2)) || state.contactDetails);

3. @RukkiesMan обновил сообщение, чтобы показать мой файл combine reducers.

4. Почему вы добавили projectContactReducer к своему вопросу, у вас не было проблем с получением contactDetails ?

Ответ №1:

Ты projectContactDetails ошибаешься. Там projectContact нет projectContactDetails состояния projectContactReducer редуктора, поэтому вы должны получить это как:

 const contactDetails = useSelector(state => state.projectContactDetails);
const { projectContact } = contactDetails;