Egon Adelsberger
Egon Adelsberger

Reputation: 85

Redux - useSelector returns state as undefined

I'm following a tutorial on learning Redux and I'm stuck at this point where state that should have an image url is returned as undefined. Image is successfully saved in firbase storage and dispatched but when I try to get the url on new route with useSelector it is undefined.

import React, {useEffect} from "react";
import {useSelector} from "react-redux";
import {useHistory} from "react-router-dom";
import "./ChatView.css";
import {selectSelectedImage} from "./features/appSlice";

function ChatView() {
    const selectedImage = useSelector(selectSelectedImage);
    const history = useHistory();

    useEffect(() => {
        if(!selectedImage) {
            exit();
        }
    }, [selectedImage])

    const exit = () => {
        history.replace('/chats');
    }

    console.log(selectedImage)

    return (
        <div className="chatView">
            <img src={selectedImage} onClick={exit} alt="" />
        </div>
        
    )
}

export default ChatView

reducer created for chat (slice):

import { createSlice } from '@reduxjs/toolkit';

export const appSlice = createSlice({
  name: 'app',
  initialState: {
    user:null,
    selectedImage:null,
  },

  reducers: {
    login: (state, action) => {
      state.user = action.payload;
    },
    logout: (state) => {
      state.user = null;
    },
    selectImage:(state, action) => {
      state.selectedImage = action.payload
    },
    resetImage:(state) => {
      state.selectedImage = null
    }
  },
});

export const { login, logout, selectImage, resetImage} = appSlice.actions;

export const selectUser = (state) => state.app.user;
export const selectSelectedImage = (state) => state.app.selectImage;

export default appSlice.reducer;

and code for dispatching that imageURL which when i console.log it gives the correct url:

import {Avatar} from "@material-ui/core";
import StopRoundedIcon from "@material-ui/icons/StopRounded"
import "./Chat.css";
import ReactTimeago from "react-timeago";
import {selectImage} from "./features/appSlice";
import {useDispatch} from "react-redux";
import {db} from "./firebase";
import {useHistory} from "react-router-dom";

function Chat({id, username, timestamp, read, imageUrl, profilePic}) {
    const dispatch = useDispatch(); 
    const history = useHistory();

    const open = () => {
        if(!read) {
            dispatch(selectImage(imageUrl));
            db.collection('posts').doc(id).set({read:true,}, {merge:true});

            history.push('/chats/view');
        }
    };

    return (
        <div onClick={open} className="chat">
            <Avatar className="chat__avatar" src={profilePic} />
            <div className="chat__info">
                <h4>{username}</h4>
                <p>Tap to view - <ReactTimeago date={new Date(timestamp?.toDate()).toUTCString()} /></p>
            </div>

            {!read && <StopRoundedIcon className="chat__readIcon" />}
        </div>
    )
}

export default Chat

Upvotes: 0

Views: 924

Answers (1)

Silvex
Silvex

Reputation: 186

Your selector is trying to access the wrong field.

export const selectSelectedImage = (state) => state.app.selectImage;

Should actually be: export const selectSelectedImage = (state) => state.app.selectedImage; as your state has selectedImage field and not selectImage.

Upvotes: 2

Related Questions