skip to Main Content

I’m trying to access the camera image from one redux file to react file .This code is from "https://www.papareact.com/" .I’m new to redux and stuck here.
This is the cameraSlice.js redux file where I’m capturing the image and storing it .

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


export const cameraSlice = createSlice({
  name: 'camera',
  initialState: {
    cameraImage:null,
  },
  // The `reducers` field lets us define reducers and generate associated actions
  reducers: {
    setCameraImage: (state, action) => {
      state.cameraImage += action.payload;
    },
    resetCameraImage: (state) => {
        state.cameraImage =null;
    }
  },
});

export const { setCameraImage, resetCameraImage } = cameraSlice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`
export const selectCameraImage= (state) => state.cameraImage.value;

export default cameraSlice.reducer;

This is the webcamCapture.js where it the image that got captured is dispatched to another url (preview)

import React, { useCallback, useRef, useState } from 'react';
import Webcam from 'react-webcam';
import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked';
import { useDispatch } from 'react-redux';
import { setCameraImage } from './features/cameraSlice';
import { useNavigate } from 'react-router-dom';
import './WebcamCapture.css';

const videoConstraints = {
    width: 250,
    height: 400,
    facingMode:"user",
};


function WebcamCapture() {
    const webcamRef=useRef(null);
    const dispatch = useDispatch();
   // BEM naming 
   const navigate = useNavigate() //const history=useHistory(); useHistory is now useNavigate in v6



    //using hook
    const capture = useCallback(()=>{
        const imageSrc = webcamRef.current.getScreenshot(); //generates base64 image
        dispatch(setCameraImage(imageSrc));
        navigate('/preview');
    }, [webcamRef])


  return (
    <div className='webcamCapture'>
    <Webcam
      audio={false}
      height={videoConstraints.height}
      ref={webcamRef}
      screenshotFormat='image/jpeg'
      width={videoConstraints.height}
      videoConstraints={videoConstraints} //object
    />

    <RadioButtonUncheckedIcon
    className='webcamCapture_button'
    onClick={capture}
    fontSize='large'
    />
    </div>
  )
}

export default WebcamCapture;

and at the end I’m accessing the cameraSlice.js function selectCameraImage in Preview.js

import React from 'react';
import './Preview.css';
import { useSelector } from 'react-redux';
import { selectCameraImage } from './features/cameraSlice';

function Preview() {
 const cameraImage= useSelector(selectCameraImage); //pulls image from redux

  return (
    <div className='preview'>
        <h2> This is your preview</h2>
        <img src={cameraImage} alt='' />
    </div>
  );
}

export default Preview;

but as soon as I click on the camera button it redirects to preview page yet gives the error

Cannot read properties of undefined (reading ‘value’)
TypeError: Cannot read properties of undefined (reading ‘value’)…
. Please help.

I was capturing image using react-webcam . I was supposed to display the image captured in the next navigation (Preview) navigation.

3

Answers


  1. This is Wrong => in your Slice File
    export const selectCameraImage= (state) => state.cameraImage.value;

    Correct Will Be

    export const selectCameraImage= (state) => state.camera.cameraImage;

    Login or Signup to reply.
    1. I’ll assume your store is setup something like:
    const reducer = combineReducers({
      camera: cameraSlice.reducer,
      ...
    })
    
    const store = createStore(reducer)
    

    Your slice is camera and your reducer setCameraImage changes the value of cameraImage within that slice state.

    1. setCameraImage concatenates the payload onto state.cameraImage itself (looks like a string) inside the camera slice, whereas your selector attempts to access .value.

    Combining the two, it appears you need to change your selector to something like the following:
    export const selectCameraImage = (state) => state.camera.cameraImage;

    You will also want to make sure you are setting the camera image with the payload as concatenating it with your initial value null will be problematic – something like:

    setCameraImage: (state, action) => {
      state.cameraImage = action.payload;
    },
    

    Then you will also want to ensure that your selector can receive the value from redux in the Preview component e.g. by wrapping your component at a higher level with the React-Redux provider https://react-redux.js.org/api/provider#basic-usage

    Login or Signup to reply.
  2. Problem: It should be accessing the cameraImage property from the state, not state.cameraImage.value

    Update the "cameraSlice.js" as this:

    export const selectCameraImage = (state) => state.camera.cameraImage;
    

    Also, you need to make below changes in "cameraSlice.js" file.

    setCameraImage: (state, action) => {
      state.cameraImage = action.payload;
    },
    

    =====================Edit=======================

    You can edit the capture variable value in the "Preview" Component, just try to add below dependency in useeffect.

    const capture = useCallback(() => {
      const imageSrc = webcamRef.current.getScreenshot(); // generates base64 image
      dispatch(setCameraImage(imageSrc));
      navigate('/preview');
    }, [webcamRef, dispatch, navigate]);
    

    And, later on – Console the cameraImage. So, you can get to know it’s still undefined or getting values.

    const cameraImage = useSelector(selectCameraImage);
    console.log(cameraImage); 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search