Невозможно прочитать свойства неопределенного (чтение «значение»)... TypeError: невозможно прочитать свойства неопределенного (чтение «значение»)

Я пытаюсь получить доступ к изображению камеры из одного файла с редукцией, чтобы реагировать на файл. Этот код взят из «https://www.papareact.com/». Я новичок в редуксе и застрял здесь. Это файл редукса cameraSlice.js, в который я записываю изображение и сохраняю его.

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;

Это webcamCapture.js, где захваченное изображение отправляется на другой URL-адрес (предварительный просмотр)

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;

и в конце я получаю доступ к функции cameraSlice.js selectCameraImage в 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;

но как только я нажимаю кнопку камеры, он перенаправляет на страницу предварительного просмотра, но выдает ошибку

Невозможно прочитать свойства undefined (чтение «значение») TypeError: Не удается прочитать свойства неопределенного (чтение «значение»)... . Пожалуйста помоги.

Я снимал изображение с помощью реактивной веб-камеры. Я должен был отобразить изображение, снятое в следующей навигации (Preview).

🤔 А знаете ли вы, что...
React поддерживает однонаправленный поток данных (unidirectional data flow) для предсказуемого управления состоянием.


1
65
3

Ответы:

Это неправильно => в вашем файле фрагмента экспортировать const selectCameraImage= (состояние) => state.cameraImage.value;

Правильно Будет

экспортировать const selectCameraImage= (состояние) => state.camera.cameraImage;


  1. Я предполагаю, что ваш магазин настроен примерно так:
const reducer = combineReducers({
  camera: cameraSlice.reducer,
  ...
})

const store = createStore(reducer)

Ваш срез — это camera, а ваш редюсер setCameraImage изменяет значение cameraImage в этом состоянии среза.

  1. setCameraImage объединяет полезную нагрузку с самим state.cameraImage (выглядит как строка) внутри фрагмента camera, в то время как ваш селектор пытается получить доступ к .value.

Сочетая два, кажется, вам нужно изменить свой селектор на что-то вроде следующего: export const selectCameraImage = (state) => state.camera.cameraImage;

Вы также захотите убедиться, что вы устанавливаете изображение камеры с полезной нагрузкой, так как объединение его с вашим начальным значением null будет проблематичным - что-то вроде:

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

Затем вы также захотите убедиться, что ваш селектор может получить значение от избыточности в компоненте предварительного просмотра, например. обернув ваш компонент на более высоком уровне с помощью провайдера React-Redux https://react-redux.js.org/api/provider#basic-usage


Решено

Проблема: он должен обращаться к свойству cameraImage из состояния, а не из state.cameraImage.value

Обновите «cameraSlice.js» следующим образом:

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

Кроме того, вам необходимо внести следующие изменения в файл «cameraSlice.js».

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

=====================Изменить=======================

Вы можете отредактировать значение переменной захвата в компоненте «Предварительный просмотр», просто попробуйте добавить ниже зависимость в useeffect.

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

И, позже - консоль cameraImage. Таким образом, вы можете узнать, что он все еще не определен или получает значения.

const cameraImage = useSelector(selectCameraImage);
console.info(cameraImage);