无法将usestate钩子值设置为相对的布尔值



我正在创建一个datepicker,并使用usestate钩子来管理其可见性。在DIV上,我添加了更改价值的事件侦听器,但它并没有我预期的。它仅第一次起作用,因此初始值更改为true,但是在第二和第三次点击时,此值保持到true和datepicker在单击时保持可见。

这是datepicker

import React, { useState } from 'react';
import OutsideClickHandler from 'react-outside-click-handler';
import { renderInfo, getWeeksForMonth } from './utils';
import {
    renderMonthAndYear,
    handleBack,
    handleNext,
    weekdays,
} from '../../utils';
const DatePicker = ({
    isOpen,
    setIsOpen,
    selected,
    setSelected,
    dayClick,
    dayClass,
}) => {
    const startDay = new Date().setHours(0, 0, 0, 0);
    const [current, setCurrent] = useState(new Date(startDay));
    const weeks = getWeeksForMonth(current.getMonth(), current.getFullYear());
    function handleClick(date) {
        if (date > startDay) {
            setSelected(date);
            setCurrent(date);
            setIsOpen(false);
            if (dayClick) {
                dayClick(date);
            }
        }
    }
    return (
        <div className="DatePicker-container">
            <div
                tabIndex="0"
                role="button"
                className="DatePicker-info"
                onKeyPress={e => {
                    if (e.which === 13) {
                        setIsOpen(!isOpen);
                    }
                }}
                onClick={e => {
                    setIsOpen(!isOpen);
                }}
            >
                {renderInfo(selected)}
            </div>
            {isOpen && (
                <OutsideClickHandler onOutsideClick={() => setIsOpen(false)}>
                    <div className="DatePicker">
                        <div className="DatePicker__header">
                            <span
                                role="button"
                                onClick={() => handleBack(current, setCurrent)}
                                className="triangle triangle--left"
                            />
                            <span className="DatePicker__title">
                                {renderMonthAndYear(current)}
                            </span>
                            <span
                                role="button"
                                onClick={() => handleNext(current, setCurrent)}
                                className="triangle triangle--right"
                            />
                        </div>
                        <div className="DatePicker__weekdays">
                            {weekdays.map(weekday => (
                                <div
                                    key={weekday}
                                    className="DatePicker__weekday"
                                >
                                    {weekday}
                                </div>
                            ))}
                        </div>
                        {weeks.map((week, index) => (
                            <div
                                role="row"
                                key={index}
                                className="DatePicker__week"
                            >
                                {week.map((date, index) =>
                                    date ? (
                                        <div
                                            role="cell"
                                            key={index}
                                            onClick={() => handleClick(date)}
                                            className={dayClass(date)}
                                        >
                                            {date.getDate()}
                                        </div>
                                    ) : (
                                        <div
                                            key={index}
                                            className="DatePicker__day--empty"
                                        />
                                    ),
                                )}
                            </div>
                        ))}
                    </div>
                </OutsideClickHandler>
            )}
        </div>
    );
};
export default DatePicker;

使用两个。

的paterangepicker
import React, { useState } from 'react';
import DatePicker from './DatePicker';
import DatePickerContext from './DatePickerContext';
import './DatePicker.scss';
const DateRangePicker = () => {
    const startDay = new Date().setHours(0, 0, 0, 0);
    const [isOpen, setIsOpen] = useState(false);
    const [isSecondOpen, setIsSecondOpen] = useState(false);
    const [selected, setSelected] = useState(new Date(startDay));
    const [secondSelected, setSecondSelected] = useState(new Date(startDay));
    function dayClass(date) {
        if (
            selected.getTime() === date.getTime() ||
            (date >= selected && date <= secondSelected)
        ) {
            return 'DatePicker__day DatePicker__day--selected';
        }
        if (date < startDay || date < selected) {
            return 'DatePicker__day DatePicker__day--disabled';
        }
        return 'DatePicker__day';
    }
    function dayClick(date) {
        setSecondSelected(date);
        setIsSecondOpen(true);
    }
    return (
        <DatePickerContext.Provider>
            <div className="DatePicker-wrapper">
                <DatePicker
                    key={1}
                    isOpen={isOpen}
                    setIsOpen={setIsOpen}
                    selected={selected}
                    setSelected={setSelected}
                    dayClick={dayClick}
                    dayClass={dayClass}
                />
                <DatePicker
                    key={2}
                    isOpen={isSecondOpen}
                    setIsOpen={setIsSecondOpen}
                    selected={secondSelected}
                    setSelected={setSecondSelected}
                    dayClass={dayClass}
                />
            </div>
        </DatePickerContext.Provider>
    );
};
export default DateRangePicker;

a(当下一个状态取决于上一个状态时(==当前(状态时,最好使用功能更新来确保使用正确的"当前"值:

setIsOpen(currentIsOpen => !currentIsOpen)

b(当由同一事件执行的多个处理程序更新下一个状态时,很难理解下一个状态。以下2个处理程序可能会在同一单击上执行(第1个Div是"外部"(:

<div ... onClick={e => setIsOpen(!isOpen)}>
<OutsideClickHandler onOutsideClick={() => setIsOpen(false)}>

如果onOutsideClick首先执行,然后用isOpen=false进行反应重新渲染,然后onClick执行第二,它将在您观察到的情况下设置isOpen=true - 我看不出重新渲染之间会如何发生,但是也许OutsideClickHandler正在做某事。邪恶或您的代码比问题更复杂。

仅执行1个活动处理程序:

<OutsideClickHandler onOutsideClick={(e) => {
  e.stopPropagation();
  setIsOpen(false);
}}>

相关内容

  • 没有找到相关文章

最新更新