从子组件更新父状态并在父状态更新时重新渲染此子

时间:2020-12-29 12:35:53

标签: javascript reactjs

我正在学习 React,我整天都在尝试解决我的问题,但没有成功。然后决定在这里提出我的第一个问题。

我有子组件,包括 React-Datepicker 组件和单独的“第二天”和“前一天”按钮来更改所选日期。

SelectedDate 存储在父组件的状态中。

我正在尝试从子组件更新父组件的状态,然后当状态更新时,子组件应重新渲染,因为此状态作为道具传递给同一个子组件。

我已设法从子组件更改父状态,但子组件未重新渲染,因此 Datepicker 日期未更新。

我该如何解决这个问题?

下面是我没有导入行的代码。

// App.js

function App() {
  const [selectedDate, setSelectedDate] = useState(new Date())

  const incrementDate = () => {
    let next = selectedDate
    next.setDate(next.getDate() + 1)

    setSelectedDate(next)
  }

  const decrementDate = () => {
    let previous = selectedDate
    previous.setDate(previous.getDate() - 1)

    setSelectedDate(previous)
  }

  return (
    <div className="App">
      <Child 
        selectedDate={selectedDate}
        setSelectedDate={setSelectedDate}
        decrementDate={decrementDate}
        incrementDate={incrementDate} />
    </div>
  )
}

// Child.js

const Child = ({ selectedDate, setSelectedDate, decrementDate, incrementDate }) => {
  return (
    <div className='datepicker-wrapper'>
      <ArrowLeft className='date-arrow' onClick={decrementDate} />
        <DatePicker
          selected={selectedDate}
          onChange={(date) => setSelectedDate(date)}
        />
      <ArrowRight className='date-arrow' onClick={incrementDate} />
    </div>
  )
}

解决方案:

增加和减少函数的变化:

let next = new Date(selectedDate.valueOf())
let previous = new Date(selectedDate.valueOf())

3 个答案:

答案 0 :(得分:1)

当你使用 React 更新状态时,你应该总是创建新的状态对象,而不仅仅是改变现有的状态。

  const incrementDate = () => {
    let next = new Date(selectedDate.valueOf())
    next.setDate(next.getDate() + 1)
    setSelectedDate(next)
  }

  const decrementDate = () => {
    let previous = new Date(selectedDate.valueOf())
    previous.setDate(previous.getDate() - 1)
    setSelectedDate(previous)
  }

React 有各种优化,以便子组件仅在状态改变时重新渲染。许多 javascript 方法(例如 Date.setDate())会在原地改变原始对象。简单地用 let previous = selectedDate 分配一个新名称不会创建新的 Date 对象。要创建新日期,您必须在更新程序函数的某处使用 new Date()

答案 1 :(得分:0)

由于您忘记添加 useEffect 钩子,子组件未呈现。

 import React,{useEffect} from 'react'

    const Child = ({ selectedDate, setSelectedDate, decrementDate, incrementDate }) => {
     useEffect(()=>{},[selectedDate]);
      return (
        <div className='datepicker-wrapper'>
          <ArrowLeft className='date-arrow' onClick={decrementDate} />
            <DatePicker
              selected={selectedDate}
              onChange={(date) => setSelectedDate(date)}
            />
          <ArrowRight className='date-arrow' onClick={incrementDate} />
        </div>
      )
    }

答案 2 :(得分:0)

我有同样的问题,用一个额外的函数来计算它的价值 从孩子开始,然后用它更新状态,而且很容易用 console.log 跟踪它。 您可以将其视为中间件。 试试看:

function App() {
  const [selectedDate, setSelectedDate] = useState(new Date())

  const incrementDate = () => {
    let next = selectedDate
    next.setDate(next.getDate() + 1)

    setSelectedDate(next)
  }
  const onDateChane = (date) => {
    console.log(date)
    setSelectedDate(date)
    }
    
  const decrementDate = () => {
    let previous = selectedDate
    previous.setDate(previous.getDate() - 1)

    setSelectedDate(previous)
  }

  return (
    <div className="App">
      <Child 
        selectedDate={selectedDate}
        setSelectedDate={setSelectedDate}
        decrementDate={decrementDate}
        incrementDate={incrementDate} />
    </div>
  )
}