I'm building a react project using redux. I'm getting this weird error, i'm not able to resolve: The error I see in my browser window:
Contacts.render C:/Users/lenovo/Desktop/contactmanager_redux/src/components/contacts/Contacts.js:18
15 | const { contacts } = this.props;
16 | return (
17 | <React.Fragment>
> 18 | <h1 className="display-4 mb-2">
| ^ 19 | <span className="text-success">Contact</span> List
20 | </h1>
21 | {contacts.map(contact => (
View compiled
▶ 22 stack frames were collapsed.
Function.mapToProps C:/Users/lenovo/Desktop/contactmanager_redux/src/actions/contactActions.js:7
4 |
5 | export const getContacts = () => async dispatch => {
6 | const res = await axios.get("https://jsonplaceholder.typicode.com/users");
> 7 | dispatch({
8 | type: GET_CONTACTS,
9 | paylaod: res.data
10 | });
View compiled
this error came out when I tried to fetch the data using axios and tried to add the payload in the reducer file. I created separate action file and then brought the code to reducer using dispatch function.
Here is my Contacts.js file:
import React, { Component } from 'react';
import Contact from './Contact';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
// import {GET_CONTACTS} from '../../actions/types';
import {getContacts} from '../../actions/contactActions';
class Contacts extends Component {
componentDidMount(){
this.props.getContacts;
}
render() {
const { contacts } = this.props;
return (
<React.Fragment>
<h1 className="display-4 mb-2">
<span className="text-success">Contact</span> List
</h1>
{contacts.map(contact => (
<Contact key={contact.id} contact={contact} />
))}
</React.Fragment>
);
}
}
Contacts.propTypes = {
contacts: PropTypes.array.isRequired,
getContacts: PropTypes.func.isRequired
}
const mapStateToProps = (state) => ({
contacts: state.contact.contacts
});
/*const mapDispatchToProps = (dispatch) => (
{
getContacts: () => (dispatch({type: GET_CONTACTS}))
}
)*/
export default connect(mapStateToProps, getContacts)(Contacts);
my ContactActions.js code:
import {GET_CONTACTS, DELETE_CONTACT, ADD_CONTACT} from './types';
import axios from 'axios';
export const getContacts = () => async dispatch => {
const res = await axios.get("https://jsonplaceholder.typicode.com/users");
dispatch({
type: GET_CONTACTS,
paylaod: res.data
});
}
export const deleteContact = (id) => {
return {
type: DELETE_CONTACT,
payload: id
}
}
export const addContact = (contact) => {
return {
type: ADD_CONTACT,
payload: contact
}
}
ContactReducer.js code:
import {GET_CONTACTS, DELETE_CONTACT, ADD_CONTACT} from '../actions/types';
const initialState = {
contacts: []
};
export default function(state = initialState, action){
switch(action.type){
case GET_CONTACTS:
return {
...state,
contacts: action.payload
};
case DELETE_CONTACT:
return {
...state,
contacts: state.contacts.filter(contact => contact.id !== action.payload)
}
case ADD_CONTACT:
return {
...state,
contacts: [action.payload, ...state.contacts]
}
default:
return state;
}
}
CodePudding user response:
Initally Contacts will not have data .Do conditional render like this so only the render will happen when data is available in contacts .
{contacts && contacts.map(contact => (
<Contact key={contact.id} contact={contact} />
))}
CodePudding user response:
There are couple of problems in your Contacts
component:
1- Since you have commented mapDispatchToProps
, actually you haven't send getContacts
function to your Contacts
component as a prop.
2- You haven't call getContacts
in the componentDidMount
. you just has wirtten this.props.getContacts;
while getContacts
must be an function and you have to call it, in order to fetch data.
I edited your MyContact.js
file a bit, please try on this:
MyContact.js
import React, { Component } from 'react';
import Contact from './Contact';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
// import {GET_CONTACTS} from '../../actions/types';
import {getContacts as fetchContacts} from '../../actions/contactActions';
class Contacts extends Component {
componentDidMount(){
this.props.getContacts();
}
render() {
const { contacts = [] } = this.props;
return (
<React.Fragment>
<h1 className="display-4 mb-2">
<span className="text-success">Contact</span> List
</h1>
{contacts.map(contact => (
<Contact key={contact.id} contact={contact} />
))}
</React.Fragment>
);
}
}
Contacts.propTypes = {
contacts: PropTypes.array.isRequired,
getContacts: PropTypes.func.isRequired
}
const mapStateToProps = (state) => ({
contacts: state.contact.contacts
});
const mapDispatchToProps = (dispatch) => (
{
getContacts: () => (dispatch(fetchContacts())
}
)
export default connect(mapStateToProps, mapDispatchToProps)(Contacts);