Я пытаюсь получить доступ к изображению камеры из одного файла с редукцией, чтобы реагировать на файл. Этот код взят из «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) для предсказуемого управления состоянием.
Это неправильно => в вашем файле фрагмента экспортировать const selectCameraImage= (состояние) => state.cameraImage.value;
экспортировать const selectCameraImage= (состояние) => state.camera.cameraImage;
const reducer = combineReducers({
camera: cameraSlice.reducer,
...
})
const store = createStore(reducer)
Ваш срез — это camera
, а ваш редюсер setCameraImage
изменяет значение cameraImage
в этом состоянии среза.
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);