简体   繁体   English

反应状态变化不触发 useEffect

[英]React state change not triggering useEffect

I have a component with the following我有一个包含以下内容的组件

const [isOpen, setIsOpen] = useState(false);
     {isOpen && (
                <Drop
                  overflow="unset"
                  align={{ right: "left", top: "bottom", bottom: "bottom" }}
                  style={{ overflowY: "scroll" }}
                  target={targetRef.current}
                  onClickOutside={() => setIsOpen(false)}
                  onEsc={() => setIsOpen(false)}
                >
                  <Calendar
                    date={
                      value
                        ? moment(value)
                            .format()
                            .split("T")[0]
                        : null
                    }
                    onSelect={evt => {
                      onCalendarSelect(evt.toString());
                    }}
                    size="small"
                    {...(calendarPassedProps as CalendarProps)}
                  />
                </Drop>
              )}

useEffect(() => {
  console.log("useEffect ",isOpen)
}, [isOpen])

Where onCalendarSelect is onCalendarSelect 在哪里

const onCalendarSelect = (v: string) => {
  console.log(isOpen) //always showing true
  setIsOpen(false)
  const date = moment(v)
    .format()
    .split("T")[0]
    .replaceAll("-", "/");
  try {
    setValue(date);
    if (onChange) {
      onChange(date);
    }
  } catch (e) {
    // Prevent invalid dates
  }
};

Now, when I click outside of the drop , and onCLickOutside is triggered, my isOpen useEffect is triggered, hence closing the calendar.现在,当我在 drop 外部单击并触发 onCLickOutside 时,我的 isOpen useEffect 被触发,从而关闭日历。

But whenever I trigger the function OnCalendarSelect which does setIsOpen(false) , nothing changes and the useeffect is not being triggered.但是,每当我触发执行setIsOpen(false)的函数 OnCalendarSelect 时,没有任何变化,并且不会触发 useeffect。

What can the issue be?问题可能是什么?

1.You are not providing a complete component example so we know if there are conflicts, if there's a different setIsOpen that overwrites the one in this component or any other bugs that might be caused by your logic. 1.您没有提供完整的组件示例,因此我们知道是否存在冲突,是否有不同的 setIsOpen 覆盖了该组件中的那个或任何其他可能由您的逻辑引起的错误。 2.You are not specifying the relationship of onCalendarSelect and this component. 2.你没有指定onCalendarSelect和这个组件的关系。 Are you passing the function as a prop?您是否将函数作为道具传递? Are you extracting it from context?你是从上下文中提取它吗? Is it defined inside the component?它是在组件内部定义的吗? 3. Do you have another setIsOpen in the app that could overwrite the one here? 3. 应用程序中是否有另一个 setIsOpen 可以覆盖这里的那个?

However.然而。 I think you should pass the setIsOpen function to your onCalendarSelect function.我认为你应该将 setIsOpen 函数传递给你的 onCalendarSelect 函数。 As in the example below.如下例所示。 If this does not work please provide the full component code and the code of the component where onCalendarSelect is.如果这不起作用,请提供完整的组件代码和 onCalendarSelect 所在组件的代码。

const [isOpen, setIsOpen] = useState(false);
     {isOpen && (
                <Drop
                  overflow="unset"
                  align={{ right: "left", top: "bottom", bottom: "bottom" }}
                  style={{ overflowY: "scroll" }}
                  target={targetRef.current}
                  onClickOutside={() => setIsOpen(false)}
                  onEsc={() => setIsOpen(false)}
                >
                  <Calendar
                    date={
                      value
                        ? moment(value)
                            .format()
                            .split("T")[0]
                        : null
                    }
                    onSelect={evt => {
                      onCalendarSelect(evt.toString(), setIsOpen);
                    }}
                    size="small"
                    {...(calendarPassedProps as CalendarProps)}
                  />
                </Drop>
              )}

useEffect(() => {
  console.log("useEffect ",isOpen)
}, [isOpen])


const onCalendarSelect = (v: string, setIsOpen: any) => {
  console.log(isOpen) //always showing true
  setIsOpen(false)
  const date = moment(v)
    .format()
    .split("T")[0]
    .replaceAll("-", "/");
  try {
    setValue(date);
    if (onChange) {
      onChange(date);
    }
  } catch (e) {
    // Prevent invalid dates
  }
};

Fixed by adding a evt.stopPropagation通过添加 evt.stopPropagation 修复

<Drop
              overflow="unset"
              align={{ right: "left", top: "bottom", bottom: "bottom" }}
              style={{ overflowY: "scroll" }}
              target={targetRef.current}
              onClickOutside={() => setIsOpen(false)}
              onClick={(evt: React.MouseEvent) => {
                evt.stopPropagation();
              }}
            >

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM