使用useReducer和React Context API时,Reducer运行两次

格雷厄姆·巴斯克斯(Graham Vasquez):

我使用React Context API以及useReducer和useContext钩子在一种奇怪的情况下陷入困境。

这是我的主要商店。

import React, { createContext, useReducer } from 'react';
import { Reducers } from './Reducers';
import { surveys } from '../../testData.json';

export const context = createContext();
const { Provider } = context;

export const Store = ({ children }) => {
  const [store, dispatch] = useReducer(Reducers, {
    editSurvey: { display: false },
    surveys,
  });
  return <Provider value={{ store, dispatch }}>{children}</Provider>;
};

这是我的Reducers函数和Action类型:

import { Actions } from './Actions';
const { DISPLAY_NEW_SURVEY, HIDE_SURVEY } = Actions;
export const Reducers = (state, action) => {
  const { type, payload } = action;
  console.log(state, action);
  switch (type) {
    case DISPLAY_NEW_SURVEY:
      return { ...state, editSurvey: { display: true } };
    case HIDE_SURVEY:
      return { ...state, editSurvey: { display: false } };
    default:
      return state;
  }
};
export const Actions = {
  DISPLAY_NEW_SURVEY: 'DISPLAY_NEW_SURVEY',
  HIDE_SURVEY: 'HIDE_SURVEY',
};

我的edit属性中有一个display属性,用于有条件地渲染反应门户,请参见下文:

import React, { useContext } from 'react';
import { EditSurveyPortal } from '../EditSurvey/EditSurveyPortal';
import { context } from '../../store/Store';

export const NavItem = ({ name, NavImage }) => {
  const { dispatch } = useContext(context);
  return (
    <div
      id={name}
      style={{ cursor: 'pointer' }}
      onClick={() => {
        dispatch({ type: 'DISPLAY_NEW_SURVEY' });
      }}
    >
      <NavImage alt={name} width={10} height={10} />
      <EditSurveyPortal />
    </div>
  );
};
import React, { useContext } from 'react';
import { createPortal } from 'react-dom';
import { context } from '../../store/Store';
import { EditSurvey } from './EditSurvey';

export const EditSurveyPortal = () => {
  const {
    store: {
      editSurvey: { display },
    },
    dispatch,
  } = useContext(context);
  return display
    ? createPortal(
        <div className="absolute top-0 left-0 w-screen h-screen z-10 flex justify-center items-center bg-gray-400 bg-opacity-50">
          <EditSurvey />
        </div>,
        document.getElementById('root'),
      )
    : null;
};

这是实际的编辑调查组件:

import React from 'react';
import { Card, CardHeader } from '../Utility/Card';
import { Close } from '../Images/Close';

export const EditSurvey = ({ dispatch }) => {
  return (
    <Card>
      <CardHeader className="flex justify-between align-center">
        <div className="inline-block relative rounded">
          <span className="absolute top-0 l-0 bg-gray-200 text-gray-800 rounded-l px-2 py-1">
            Title
          </span>
          <input type="text" className="rounded p-1" />
        </div>
        <div
          className="text-gray-800"
          style={{ cursor: 'pointer' }}
          onClick={() => {
            dispatch({ type: 'HIDE_SURVEY' });
          }}
        >
          <Close width={8} height={8} />
        </div>
      </CardHeader>
    </Card>
  );
};

我的问题是,当我单击门户网站上的关闭按钮时,它将调度HIDE_SURVEY,然后立即调度DISPLAY_NEW_SURVEY:

页面截图

我一生无法解决这个问题。任何帮助将不胜感激。

谢谢!

普拉泰克·塔帕(Prateek Thapa):

事件冒泡,伙伴。

这里的问题是您EditSurvey位于NavItem的可点击区域之下。这里发生的是,当您在中单击该div时EditSurvey,它将首先注册对该div的点击,然后冒泡直至您的NavItem可点击div。这基本上就是所谓的event-bubbling

您可以在此处了解事件冒泡和捕获的信息

此外,您可以检查事件冒泡问题在这里

为了阻止事件冒泡,您可以简单地停止事件的传播。

<div
    className="text-gray-800"
    style={{ cursor: 'pointer' }}
    onClick={(event) => {
      event.stopPropagation();
      dispatch({ type: 'HIDE_SURVEY' });
    }}
  >
    <Close width={8} height={8} />
  </div>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

React useReducer Hook发射两次/如何将道具传递给reducer?

Context Broker仅在被询问两次时才响应

使用Model.find()调用MongoDB时,KeystoneJS中间件运行两次

React Context API和HOC

React Context API无法绑定“ this”

使用React useContext和useReducer时出现打字稿错误

如何使用React Context API?

在React中使用Context API和功能组件作为服务

使用React Context和useReducer防止在todo应用中重新渲染未更改的项目

使用useReducer / useContext和React-Testing-Library时出现“ TypeError:分派不是函数”

React for循环仅运行两次

React Hook useReducer始终运行两次

React Context API与本地存储

创建新对象时,使用React Context API更新组件

Reducer代码第一次运行,但是连续两次仅执行Actions代码,而没有执行Reducer代码?| React-Native和Redux

React Hook setstate运行两次

使用Typescript的React的Context API

React Context API +钩子

(React Context Beginner)使用react-rooter-dom更改页面时,React Context不统计

在一个ActionResult中两次运行.ExecuteStoreCommand时出错“参数已使用”

为什么使用--login时bash.exe运行两次?

使用 React Context API 时,无法获取数据

使用 useReducer 和 Context 与 Typescript 键入错误

使用不同的参数运行两次 tumblr API 调用以返回不同的数据

React Hook + Context api

使用 react-router-dom 和 React 的 Context API 的意外输出

使用 setdelay 运行两次的函数

使用 Context API 和 useContext (React js) 传递值

React useContext & useReducer - 在应用程序中需要全局状态,对使用一个和多个 reducer 感到困惑