setter 方法会在 React 中触发 DOM 重新渲染吗?

Do setter methods trigger a DOM rerender in React?

我正在通过做一个基本的日历应用程序来学习 React,这在很大程度上依赖于使用 Date() 对象。我正在尝试显示选定的月份,通过单击几个字体很棒的箭头图标可以更改它。

使用上下文 API 和 useState,我正在使用“setDateObject”回调更新日期,它使用日期对象的 setter 函数“setMonth()”。

只是做一些控制台日志显示日期已成功更新状态,但

标记中显示的日期未被重新呈现。我尝试用硬类型对象切换日期对象,并在“incrementMonth”方法中手动递增月份,这确实会触发重新渲染。

所以要么我误解了什么,要么使用 setter 函数更新日期对象并没有触发重新渲染。有人有过这方面的经验吗?

提前致谢!

对象

import React, { useContext } from "react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"

// Styling
import style from "../styles/Calendar.css"

// Assets
import { faArrowLeft } from "@fortawesome/free-solid-svg-icons"
import { faArrowRight } from "@fortawesome/free-solid-svg-icons"

// Contexts
import { DateContext } from "./context/DateContext.js"

const Calendar = () =>  {
    const [dateObj, setDateObj] = useContext(DateContext)
    const monthArray = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

    const incrementMonth = () => {
        setDateObj(prevDate => {
            let newDate = prevDate
            newDate.setMonth(prevDate.getMonth() + 1)
            return newDate
        })
    }
    
    const decrementMonth = () => {
        setDateObj(prevDate => {
            let newDate = prevDate
            newDate.setMonth(prevDate.getMonth() - 1)
            return newDate
        })
    }
    
    return(
        <div style={style} className="CalendarWrapper">
            <div className="MonthSelector">
                <FontAwesomeIcon icon={faArrowLeft} onClick={decrementMonth} className="hoverArrow"/>
                <p>{ `${ monthArray[dateObj.getMonth()] } ${ dateObj.getFullYear() }` }</p>
                <FontAwesomeIcon icon={faArrowRight} onClick={incrementMonth} className="hoverArrow"/>
            </div>
        </div>
    )
}

export default Calendar

上下文

import React, { useState, createContext } from "react"

export const DateContext = createContext(null)

export const DateProvider = props => {
    const [dateObj, setDateObj] = useState(new Date())
    return(
        <DateContext.Provider value={[dateObj, setDateObj]}>
            {props.children}
        </DateContext.Provider>
    )
}

React 试图在 re-rendering 上变得聪明。如果新状态和旧状态引用相同的值,it doesn't re-render.

您实际上是在用相同的日期对象调用 setDateObj,即使您已经更改了它的内部数据。换句话说,如果newDate === prevDate,则不会re-render。您可以通过这样复制日期来避免这种情况:

const newDate = new Date(prevDate);