#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
});
}
};
Вот как выглядит ответ от сервера в моих инструментах разработки:
я предполагаю, что это как-то связано с данными, которые не заполняются перед 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;