为什么Dispatch不起作用并使应用程序崩溃



所以基本上我有一个状态为isHamburgerIsOpen的reducer。这是为了检查汉堡图标是否被点击,我想模糊我的背景:

import React, {useEffect, useState } from 'react'
import { useCookies } from "react-cookie";
import { useHistory } from "react-router-dom";
import { useSelector } from 'react-redux';
import { ThemeProvider } from 'styled-components';
import theme from '../Themes/Themes';
import Background from '../styledComponents/Background';
import LeftMainInfo from '../components/Main/Left/LeftMainInfo';
import RightMainInfo from '../components/Main/Right/RightMainInfo';
import FlexWrapper from '../styledComponents/FlexWrapper';
import MenuSide from '../components/Main/Menu/MenuSide';
const Main = () => {
const isHamburgerIsOpen = useSelector(({appStatesReducer})=> appStatesReducer.main.isHamburgerIsOpen);
const blur = () => {
if(isHamburgerIsOpen === true){
return 'blur(20px)'
}
else{
return null
}
}
const history = useHistory();
const [cookies] = useCookies();
const [isAuth, setIsAuth] = useState(false);
useEffect(() => {
const checkAuth = async () => {
try{
const res = await fetch('http://localhost:5000/checkAuth', {
method: 'POST',
body: JSON.stringify({ jwt: cookies.jwt }),
headers: { 'Content-Type': 'application/json' }
})
const data = await res.json();
if(data.isAuth === true){
setIsAuth(true)
}
else{
history.push("/");
}
}
catch(err) {
console.log(err)
}
}
checkAuth();
},);

// start coding
if(isAuth === false) return <h1>Loading...</h1>
if(isAuth === true) return (
<ThemeProvider theme={theme}>
<Background blur={blur}  bgPosition='center' url={process.env.PUBLIC_URL + '/night.jpg'} position='relative'>
<FlexWrapper direction='row' justify='space-between' align='flex-start' padding='70px 150px 0px 60px'>
<LeftMainInfo />
<RightMainInfo />
</FlexWrapper>
<MenuSide />
</Background>
</ThemeProvider>
)
}

export default Main;

在这里,我从redux下载该状态的状态,然后我检查状态并设置背景模糊

import React, {useRef, useState} from 'react';
import { useDispatch } from 'react-redux';
import {CHANGE_ISHAMBURGERISOPEN} from '../../../actions/index';
import BarSearchWidget from '../Left/BarSearchWidget';
import SideBar from '../SideBar/SideBar';
import gsap from 'gsap';
const MenuSide = () => {
const dispatch = useDispatch();
const wrapper = useRef(null);
const [isLoupeOpen, setIsLoupeOpen] = useState(false);
const [isHamburgerOpen, setIsHamburgerOpen] = useState(false);
const showLoupe = () => {
const [elements] = wrapper.current.children;
const searchForm = elements.getElementsByClassName("search");
const loupe = elements.getElementsByClassName("loupe");
gsap.set(searchForm, { transformOrigin: "0% 100%" });
const t1 = gsap.timeline({ defaults: { ease: "power3.inOut" } });
if(!isLoupeOpen){
t1.fromTo(searchForm, { scaleX: 0 }, { duration: 1, autoAlpha: 1, scaleX: 1 });
t1.fromTo(loupe, {x: '-=0'}, {duration: 1, x: '+=265'})
setIsLoupeOpen(!isLoupeOpen)
}
else{
t1.fromTo(loupe, {x: '+=0'}, {x: '-=265', duration: 1})
t1.fromTo(searchForm, { scaleX: 1 }, {duration: 1, autoAlpha: 0, scaleX: 0 });
setIsLoupeOpen(!isLoupeOpen)
}
}
const sayHello = () => {

const [elements] = wrapper.current.children;
const sidebar = elements.getElementsByClassName("sidebar");
gsap.set(sidebar, { transformOrigin: "50% 100%" });
const t1 = gsap.timeline({ defaults: { ease: "power3.inOut" } });
if(!isHamburgerOpen){
dispatch(CHANGE_ISHAMBURGERISOPEN())
t1.fromTo(sidebar, { scaleY: 0 }, { duration: 1, autoAlpha: 1, scaleY: 1 });
setIsHamburgerOpen(!isHamburgerOpen)
}else{
}
}
return (
<div ref={wrapper}>
<div>
<BarSearchWidget showLoupe={showLoupe} sayHello={sayHello}/>
<SideBar />
</div>
</div>
)
}
export default MenuSide

在这里我动画我的东西,但在sayHello函数点击后,我想调度以更改状态,但我得到了错误:在此处输入图像描述

还有我的重复和行动:

let appStates = {
main: {
isHamburgerIsOpen: false
}
}
const appStatesReducer = (state = appStates, action) => {
switch(action.type){
case 'CHANGE_ISHAMBURGERISOPEN':
return !state
default:
return state;
}
}
export default appStatesReducer;

export const REQUEST_SUCCESS = (n) => {
return {
type: 'REQUEST_SUCCESS',
payload: n
}
}
export const CHANGE_ISHAMBURGERISOPEN = () => {
return {
type: 'CHANGE_ISHAMBURGERISOPEN'
}
}

我认为您的减速器有问题。让我们仔细看看:

const appStatesReducer = (state = appStates, action) => {
switch (action.type) {
case 'CHANGE_ISHAMBURGERISOPEN':
return !state
default:
return state;
}
}

响应CHANGE_ISHAMBURGERISOPEN时,您要做的是更改isHamburgerIsOpen标志的值,仅此而已。然而,在这段代码中,您实际要做的是用布尔值覆盖整个状态。

当您第一次调用操作时,由于状态有一个初始值,因此!state将被求值为false这意味着您的状态现在将设置为false,并且您在appStates中定义的整个结构将不复存在

这就是你得到Cannot read property 'isHamburgerIsOpen' of undefined背后的原因,可能是当这条线运行时:

const isHamburgerIsOpen = useSelector(
({ appStatesReducer }) => appStatesReducer.main.isHamburgerIsOpen
);

由于appStatesReducer现在的值为false,因此它既没有称为main的属性,也没有称为isHamburgerIsOpen的属性。这就是导致出现异常的原因。

为了解决此问题,您需要修复减速器,以便只更新当前状态的isHamburgerIsOpen属性

const appStatesReducer = (state = appStates, action) => {
switch (action.type) {
case 'CHANGE_ISHAMBURGERISOPEN':
return {
...state,
main: {
...state.main,
isHamburgerIsOpen: !state.main.isHamburgerIsOpen,
},
};
default:
return state;
}
}

当修改减速器时,你需要确保初始状态的结构始终保持不变,否则这种错误可能会再次发生。

最新更新