Component is not showing. I don't get any error messages. I am trying to fetch data from a url and build a simple list on PollList from that data. I can console.log(polls) from the action and it works but it just doesn't build the list
Here is the code.
pollsactions.js
import { GET_POLLS, POLLS_LOADING } from './types';
export const getPolls = () => dispatch => {
return fetch(URL)
.then(res => res.json())
.then(polls => {
dispatch({
type: GET_POLLS,
payload: polls
})
})
}
pollsreducers.js
import {
GET_POLLS,
POLLS_LOADING
} from '../actions/types';
const pollReducer = (state = [], { type, payload }) => {
switch (type) {
case GET_POLLS:
return payload
default:
return state
}
}
export default pollReducer;
PollList.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { getPolls } from '../redux/actions/pollsActions';
class PollList extends Component {
componentDidMount() {
this.props.getPolls();
}
render() {
const { polls } = this.props.polls
return (
<div>
{
polls && polls.map((poll) => (
<div key={poll.id}>
{(poll.type)}
</div>
))
}
</div>
)
}
}
const mapStateToProps = state => ({
polls: state.polls
});
export default connect(
mapStateToProps,
{ getPolls }
)(PollList);
You are destructuring polls incorrectly. polls is on this.props based on your mapStateToProps(), not on this.props.polls. Try changing:
const { polls } = this.props.polls;
to:
const { polls } = this.props;
Otherwise, without destructuring, it would look like:
const polls = this.props.polls;
Hopefully that helps!
Related
I've been trying to dispatch a function that will call an async parse cloud function. It worked well in my other projects when i used them in functions. But this is the first time i'm using them in a component and when i call the dispatch from map dispatch to props, I get this error. Please help me out.
ProfileHeader.js
import React, { Component } from 'react';
import Cover_Image from './Cover_Image.jpg';
import Profile_Pic from './Profile_Pic.svg';
import './ProfileHeader.css';
import { connect } from 'react-redux';
import { fetchUserProfile } from '../../Redux/UserProfile-Redux/UserProfileActionMethods';
class ProfileHeader extends Component {
componentDidMount() {
this.props.fetchUserProfile()
}
render() {
return (
<div className="profile-header-layout"></div>
)
}
}
const mapStatetoProps = (state) => {
return {
profile: state.UserProfile
}
}
const mapDispatchtoProps = (dispatch) => {
return {
fetchUserProfile: () => { dispatch(fetchUserProfile()) }, dispatch,
}
}
export default connect(mapDispatchtoProps, mapStatetoProps)(ProfileHeader)
The action Method:
import Parse from 'parse/dist/parse.min.js';
import { FETCH_USERPROFILE_FAILURE, FETCH_USERPROFILE_REQUEST, FETCH_USERPROFILE_SUCCESS } from './UserProfileActions';
const params = { username: "prvnngrj" }
export const fetchUserProfileRequest = () => {
return {
type: FETCH_USERPROFILE_REQUEST
}
}
export const fetchUserProfileSuccess = (userprofiles) => {
return {
type: FETCH_USERPROFILE_SUCCESS,
payload: userprofiles
}
}
export const fetchUserProfileFailure = (error) => {
return {
type: FETCH_USERPROFILE_FAILURE,
payload: error
}
}
export const fetchUserProfile = () => {
return async dispatch => {
dispatch(fetchUserProfileRequest)
try {
const responsedata = await Parse.Cloud.run("GetUserProfileForUsername", params);
const userprofiles = responsedata;
dispatch(fetchUserProfileSuccess(userprofiles))
}
catch (error) {
const errorMessage = error.message
dispatch(fetchUserProfileFailure(errorMessage))
}
}
}
Please ignore parts of code which do not make it relevant, its straight from the project
You mixed up the order of your arguments, so this.props.dispatch is actually your state!
You need to change
export default connect(mapDispatchtoProps, mapStatetoProps)(ProfileHeader)
to:
export default connect(mapStatetoProps, mapDispatchtoProps)(ProfileHeader)
If you can switch to function components and the useSelector/useDispatch hooks you should. This is the current recommended approach and it's easier to use.
I use the API to get Quotes, but I get an Unhandled Rejection error "(TypeError): this.props.message.map is not a function" https://ibb.co/dWqhjXK, I used debugger checked props saw that I get answers https://ibb.co/wM3mLb9 what then could be the reason? why am i getting this error? here is my code
Message.jsx
import React from 'react';
export class Message extends React.Component {
render() {
const list = this.props.message.map((item, index) => {
return <div key={index}>
<p>{item.content}</p>
</div>
});
return (
<div>
<p>{list}</p>
</div>
);
}
}
MessageContainer.js
import React from 'react';
import {connect} from "react-redux";
import {Message} from "./Message";
import {getMessageThunk} from "../../redux/message-reducer";
class MessageContainer extends React.Component {
componentDidMount() {
this.props.getMessageThunk();
}
render() {
return <Message {...this.props} />
}
}
const mapStateToProps = (state) => ({
message: state.message.users
})
export default connect(mapStateToProps, {getMessageThunk})(MessageContainer);
message-reducer.js
import {messageAPI} from "../Api/Api";
const MESSAGE = 'MESSAGE';
let initialState = {
users: [],
};
export const messageReducer = (state = initialState, action) => {
switch (action.type) {
case MESSAGE: {
return {...state, users: action.users}
}
default:
return state;
}
}
export const messageCreator = (users) => {
return {
type: MESSAGE, users
}
};
export const getMessageThunk = (users) => (dispatch) => {
messageAPI.getMessageAPI(users).then(response => {
dispatch(messageCreator(response.data));
})
}
Api.js
import * as axios from "axios";
const instance = axios.create({
withCredentials: true,
url: 'https://quotes15.p.rapidapi.com/quotes/random/',
headers: {
'x-rapidapi-key': 'bf490d72a0msh3bf159a87e0c27fp107a51jsn062ca1b9b00e',
'x-rapidapi-host': 'quotes15.p.rapidapi.com'
}
});
export const messageAPI = {
getMessageAPI() {
return instance.get(`https://quotes15.p.rapidapi.com/quotes/random/`)
},
};
Your message is not an array but an object. You do not have anything to iterate over there you could either simply return this.props.message.content but this is not a list.
const item = <p>{this.props.message.content}</p>
I'm on my Home Component where I need to show the article feed and for that, I have to have the articleList array. But for some reason when I look into the store, articleList is null. Also, the console.log that I have placed after fetching the data is also not working. It all seems strange.
Home.js
import React, { Component } from "react"
import { connect } from "react-redux"
import { listAllArticles } from "../actions/articles"
class Home extends Component {
componentDidMount() {
this.props.dispatch(listAllArticles)
}
render() {
console.log(this.props)
return (
<div style={{ textAlign: "center" }}>
<h1>Conduit</h1>
<h5>A place to share your knowledge</h5>
</div>
)
}
}
const mapStateToProps = (state) => {
return state
}
export default connect(mapStateToProps)(Home)
listAllArticles
export const listAllArticles = () => {
console.log("inside listAllArticles action creator")
return dispatch => {
fetch("https://conduit.productionready.io/api/articles")
.then(res => res.json())
.then(data => {
console.log(data.articles)
dispatch({
type: "LIST_ALL_ARTICLES",
data: data.articles
})
})
}
}
articleReducer
const initState = {
articleList: null
}
export const articleReducer = (state=initState, action) => {
console.log("inside article reducer")
switch(action.type) {
case "LIST_ALL_ARTICLES":
return {...state, articleList: action.data}
default:
return state
}
}
I am in learning phase of react, and creating small application which fetches user wishlist from firebase table and updated redux store and I am trying to access that redux store in render method but when i console.log this.props.wishlist in render method its shows null. Redux state is updated correctly. Checked with redx dev tool.
redux state screenshot
Action creator which gets wishlist data from firebase API
export const fetchWishlist = (email)=> {
return dispatch => {
dispatch(fetchWishlistStart());
let rawMovieId=[];
let uniqueMovieIdList = [];
const queryParams ='?orderBy="email"&equalTo="'+email+'"';
axios.get('https://movie-project-6fc34.firebaseio.com/wishlist.json'+queryParams)
.then (response=>{
for(let key in response.data){
rawMovieId.push(response.data[key].movieId)
}
uniqueMovieIdList = [ ...new Set(rawMovieId) ];
dispatch(fetchMovieDetailsForWishlist(uniqueMovieIdList))
})
.catch(error=> {
console.log(error);
})
}
}
export const setMovieDetailsForWishlist = (movieDetailsList)=> {
return {
type:actionType.SET_MOVIEDETAILS_WISHLIST,
movieDetailsList:movieDetailsList
}
}
export const fetchMovieDetailsForWishlist = (movieList) => {
return dispatch => {
dispatch(fetchWishlistSuccess());
let updatedMovieList = []
movieList.map((currItem)=>{
let final_api_url = api_url+movieDetails_api_end_point+currItem+api_key+'&language='+language
axios.get(final_api_url)
.then(response=>{
updatedMovieList.push({
title:response.data.title,
movieId:response.data.id,
poster:response.data.poster_path
})
})
.catch(error=>{
console.log(JSON.stringify(error));
})
})
dispatch(setMovieDetailsForWishlist(updatedMovieList));
}
}
WhislistReducer --
import * as actionType from '../actions/actionType.js'
const intialState = {
wishList:null,
showLoader:false
}
const wishListReducer = (state=intialState, action) => {
switch (action.type) {
case actionType.FETCH_WISHLIST_START:
return {
...state,
showLoader:true
}
case actionType.FETCH_WISHLIST_SUCCESS:
return {
...state,
showLoader:false
}
case actionType.SET_MOVIEDETAILS_WISHLIST:
return {
...state,
showLoader:false,
wishList:action.movieDetailsList
}
default:
return state
}
}
export default wishListReducer;
wishlist component
import React, { Component } from 'react';
import {connect} from 'react-redux';
import {withRouter} from 'react-router-dom';
import * as action from '../store/actions/index'
export class Wishlist extends Component {
componentDidMount() {
this.props.fetchWishlist(window.localStorage.getItem('email'));
render() {
let wishListPageContent = '<div> Loading........</div>'
let userWishlistDetails = this.props.wishlist
console.log(userWishlistDetails);
if (!this.props.showLoader) {
wishListPageContent = (
<div> wishlist component</div>
)
}
return (
<div>
{wishListPageContent}
</div>
);
}
}
const mapStateToProps = state => {
return {
userEmail:state.authState.userEmail,
wishlist:state.wishlistState.wishList,
isAuthSuccess:state.authState.isAuthSuccess,
showLoader:state.wishlistState.showLoader
}
}
const mapDispatchToProps = dispatch => {
return {
fetchWishlist:(email)=>dispatch(action.fetchWishlist(email)),
fetchMovieDetailsForWishlist:(movieList)=>dispatch(action.fetchMovieDetailsForWishlist(movieList))
}
}
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(Wishlist));
**Hello! my problem is my state is not uploading, is always empty altough my actions brings data correct. Can anyone give me some help of what am I doing wrong ?
I think is something with the name or the combine reducers part.
Maybe I am not accesing data correct with my reducer or something like that **
The object I receive from the api call has this format {categories: Array(4), items: Array(50)}
Component
import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ItemList from '../components/ItemList/ItemList';
import { getItems } from './actions'
class ItemListContainer extends PureComponent {
async componentDidMount() {
const { getItems } = this.props;
await getItems()
console.log(this.props)
}
render() {
return <ItemList />;
}
}
const mapStateToProps = state => (
{
items: state.items.items,
});
const mapDispatchToProps = dispatch =>
bindActionCreators(
{
getItems,
},
dispatch,
);
export default connect(mapStateToProps, mapDispatchToProps)(ItemListContainer);
actions.js
export const GET_ITEMS = 'GET_ITEMS';
export const GET_ITEM = 'GET_ITEM';
export const GET_ITEM_DESCRIPTION = 'GET_ITEM_DESCRIPTION';
export function getItems(query) {
return async function (dispatch) {
// const res = await fetch(`http://localhost:3000/api/items?q=${query}`)
const res = await fetch(`http://localhost:3000/api/items?q=ipad`)
const items = await res.json()
return dispatch({
type: 'GET_ITEMS',
items: items.items,
})
}
}
reducer.js
import { GET_ITEMS } from './actions';
const initialState = {
items: [],
itemsLoaded: false,
};
export default function(state = initialState, action) {
const { type, data } = action;
switch (type) {
case GET_ITEMS:
return {
...state,
items: data,
itemsLoaded: true,
};
default: {
return {
...state
}
}
}
}
I was accessing { data} in the reducer which of course it was empty. The correnct action was items.