当前位置:  开发笔记 > 编程语言 > 正文

即使状态已更改,成功的调度也不会导致重新渲染

如何解决《即使状态已更改,成功的调度也不会导致重新渲染》经验,为你挑选了1个好方法。

尽管我的状态成功更新(通过console.log和redux devtools检查)但我无法重新渲染我的视图

您可以在https://github.com/attendanceproject/djattendance/tree/attendance-redux/ap/static/react-gulp/app上查看代码

大多数代码都在scripts文件夹中,与我的问题有关的最重要的部分如下.每次在WeekBar组件中按下上一个或下一个按钮时,我都会尝试重新渲染,以便相应地更新日期.

容器代码

class Attendance extends Component {
  render() {
    const { dispatch, trainee, date, events, rolls, slips, selectedEvents } = this.props
    console.log('this.props', this.props)
    return (
      
dispatch(prevWeek(date))} onNextClick={date => dispatch(nextWeek(date))}/>

) } } Attendance.propTypes = { trainee: PropTypes.shape({ name: PropTypes.string, id: PropTypes.number, active: PropTypes.bool }).isRequired, date: PropTypes.object.isRequired, events: PropTypes.array.isRequired, rolls: PropTypes.array.isRequired, slips: PropTypes.array.isRequired, selectedEvents: PropTypes.array } function select(state) { return { trainee: state.trainee, date: state.date, events: state.events, rolls: state.rolls, slips: state.slips, selectedEvents: state.selectedEvents, } } export default connect(select)(Attendance)

组件代码

export default class WeekBar extends Component {
  render() {
    console.log("render props", this.props)
    // var startdate = this.props.date.weekday(0).format('M/D/YY');
    // var enddate = this.props.date.weekday(6).format('M/D/YY');
    return (
      
{this.props.date.weekday(0).format('M/D/YY')} to {this.props.date.weekday(6).format('M/D/YY')}
); } handlePrev(e) { console.log("hello!", e) this.props.onPrevClick(this.props.date) } handleNext(e) { this.props.onNextClick(this.props.date) } } WeekBar.propTypes = { onPrevClick: PropTypes.func.isRequired, onNextClick: PropTypes.func.isRequired, date: PropTypes.object.isRequired, }

减速机代码

var date = moment()
function handleWeek(state = date, action) {
  switch (action.type) {
    case PREV_WEEK:
      console.log('PREV_WEEK')
      return Object.assign({}, state, {
        date: action.date.add(-7, 'd')
      })
    case NEXT_WEEK:
      return Object.assign({}, state, {
        date: action.date.add(7, 'd')
      })
    default:
      return state
  }
}

export default handleWeek

Dan Abramov.. 19

我没有仔细观察,但您似乎使用Moment.js日期作为模型的一部分.具体来说,onNextClick发送一个动作:dispatch(nextWeek(date)).

动作创建者只是通过Moment.js日期:

export function nextWeek(date) {
    return {type: NEXT_WEEK, date}
}

最后,reducer 通过调用add以下内容来改变日期对象:

return Object.assign({}, state, {
  date: action.date.add(7, 'd') // wrong! it's mutating action.date
})

来自Moment.js add文档:

通过增加时间来改变原始时刻.

但是我们在Redux文档中强调减速器必须是纯粹的,并且状态绝不能变异,或者React Redux不会看到变化.这使Redux变得高效,因为它只重新呈现它知道已经改变的内容.

我建议的解决方案是停止使用Moment.js作为你所在州的一部分.使用常规JavaScript Date对象,确保永远不会改变它们,并且只在组件的render方法中使用Moment.js .

最后,传递从当前状态派生的数据是一种反模式.您的操作目前看起来像这样:

{type: NEXT_WEEK, date}

但这是太多的信息!reducer已经知道了该州的当前日期,因此无需通过它.

相反,您可以在没有日期的情况下触发操作:

{type: NEXT_WEEK}

并教你的减速器在计算新的时候使用当前的日期.

假设您更改了代码以保持Date对象处于状态,您可以使用vanilla JS Date API(虽然它Date也是可变的,但它不是很好):

// create a copy of the date object
let newDate = new Date(state.date.getTime());

// mutating here is fine: we mutate a new object
newDate.setDate(newDate.getDate() + 7);

return Object.assign({}, state, {
  date: newDate
})

或者,您可以使用一个名为date-fns的精美新库,它包含不变性:

import addDays from 'date-fns/add_days';

// ...

return Object.assign({}, state, {
  date: addDays(state.date, 7) // non mutating! :D
})

如果您注意永远不要改变状态或操作并始终在数据更改时创建新对象,React Redux将正确更新React组件以响应这些更改.



1> Dan Abramov..:

我没有仔细观察,但您似乎使用Moment.js日期作为模型的一部分.具体来说,onNextClick发送一个动作:dispatch(nextWeek(date)).

动作创建者只是通过Moment.js日期:

export function nextWeek(date) {
    return {type: NEXT_WEEK, date}
}

最后,reducer 通过调用add以下内容来改变日期对象:

return Object.assign({}, state, {
  date: action.date.add(7, 'd') // wrong! it's mutating action.date
})

来自Moment.js add文档:

通过增加时间来改变原始时刻.

但是我们在Redux文档中强调减速器必须是纯粹的,并且状态绝不能变异,或者React Redux不会看到变化.这使Redux变得高效,因为它只重新呈现它知道已经改变的内容.

我建议的解决方案是停止使用Moment.js作为你所在州的一部分.使用常规JavaScript Date对象,确保永远不会改变它们,并且只在组件的render方法中使用Moment.js .

最后,传递从当前状态派生的数据是一种反模式.您的操作目前看起来像这样:

{type: NEXT_WEEK, date}

但这是太多的信息!reducer已经知道了该州的当前日期,因此无需通过它.

相反,您可以在没有日期的情况下触发操作:

{type: NEXT_WEEK}

并教你的减速器在计算新的时候使用当前的日期.

假设您更改了代码以保持Date对象处于状态,您可以使用vanilla JS Date API(虽然它Date也是可变的,但它不是很好):

// create a copy of the date object
let newDate = new Date(state.date.getTime());

// mutating here is fine: we mutate a new object
newDate.setDate(newDate.getDate() + 7);

return Object.assign({}, state, {
  date: newDate
})

或者,您可以使用一个名为date-fns的精美新库,它包含不变性:

import addDays from 'date-fns/add_days';

// ...

return Object.assign({}, state, {
  date: addDays(state.date, 7) // non mutating! :D
})

如果您注意永远不要改变状态或操作并始终在数据更改时创建新对象,React Redux将正确更新React组件以响应这些更改.

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有