无状态组件在行动后不会收到新的道具

时间:2017-09-21 16:09:06

标签: reactjs redux react-redux

我有一个反应组件ReorderComponent,它呈现一个由redux商店传递的列表。 我将列表包装在“react-reorder”的重新排序组件中,当用户更改列表的顺序时,我将dipatch函数作为更新商店的道具传递。

这个步骤已成功完成,因为我可以看到商店更新,主容器接收到新状态,并带有重新排序的列表。

但是,当状态发生变化时,我的ReorderComponent不会更新它的道具。

结构如下:

-RequestContainer.js

  • 接收状态并将州和dipsatch映射到道具

- 连接到ReorderComponent

-ReorderComponent.js

-stateless组件,它接收道具以呈现列表并处理重新订购事件。

import React from 'react'
import CitiesListReorder from '../components/CitiesListReorder'
import { connect } from 'react-redux'
import { setCity, setOrder, removeCity, setNumDays, setPreferences } from '../actions'

const mapStateToProps = state => {
  console.log('passing as props:\ncities', state[Object.keys(state).length - 1].cities)
  return {
    cities: state[Object.keys(state).length - 1].cities,
    fID: Object.keys(state).length -1,
    preferences: state[Object.keys(state).length - 1].preferences,
  }
}

const mapDispatchToProps = dispatch => {
  return {
    onRemoveClick: (fID, index) => {
      dispatch(removeCity(fID, index))
    },
    onEditClick: (fID, value, index) => {
      dispatch(setCity(fID, value, index))
    },
    onSetNumDays: (fID, index, days ) => {
      dispatch(setNumDays(fID, index, days))
    },
    onSetPrefences: (fID, pref_type, info) => {
      dispatch(setPreferences(fID, pref_type, info))
    },
    onReOrder: (fID, prevIndex, nextIndex) => {
      dispatch(setOrder(fID, prevIndex, nextIndex))
    }
  }
}

const RequestContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(CitiesListReorder)

export default RequestContainer

import React from 'react'
import PropTypes from 'prop-types'
import City  from '../components/City'
import removeCity from '../actions'
import Preferences from './Preferences'
import Reorder, { reorder, reorderImmutable, reorderFromTo, reorderFromToImmutable } from 'react-reorder';


const CitiesListReorder = ({ fID, cities, preferences, onRemoveClick,
  onEditClick, onSetNumDays, onSetPrefences, onReOrder }) => {
  console.log('inside cities list reorder')
  return(
    <div>
      <Reorder
        reorderId="my-list"
        reorderGroup="reorder-group"
        component="ul"
        placeholderClassName="placeholder"
        draggedClassName="dragged"
        lock="horizontal"
        holdTime={100}
        onReorder={ (event, prevIndex, nextIndex) => {onReOrder(fID, prevIndex, nextIndex)} }
        autoScroll={true}
        disabled={false}
        disableContextMenus={true}
        placeholder={
          <div className="custom-placeholder" />
        }
      >
        {
          cities.map((city, index) => (
            <li key = {'li' + index} >
              <City
                key = {'city' + index}
                cityIndex = {index}
                city = {city}
                flightID = {fID}
                onRemoveClick = { onRemoveClick }
                onEditClick = { onEditClick }
              />
          </li>
          ))
        }
      </Reorder>
      {cities.length > 1
        ?
            <Preferences
            fID = { fID }
            numCities = { cities.length }
            preferences = { preferences }
            onSetPrefences = { onSetPrefences }
          />
        :
          null
      }
    </div>
  )
}

CitiesListReorder.propTypes = {
  fID: PropTypes.number.isRequired,
  cities: PropTypes.array.isRequired,
  preferences: PropTypes.object.isRequired,
  onRemoveClick: PropTypes.func.isRequired,
  onEditClick: PropTypes.func.isRequired,
  onSetNumDays: PropTypes.func.isRequired,
  onSetPrefences: PropTypes.func.isRequired,
  onReOrder: PropTypes.func.isRequired,
}


export default CitiesListReorder

enter image description here

在这张图片中,我们可以看到在状态改变之后,哑组件没有更新它的道具,因为它没有记录任何东西。

减速机:

case SET_ORDER:
      return {
        ...state,
        [action.fID]: Object.assign(
          {},
          state[action.fID],
          {cities: setOrder(state[action.fID].cities, action.prevIndex, action.nextIndex)}
        )
      }
      
 export function setOrder(cities, prevIndex, nextIndex){
  var first = cities[prevIndex]
  var second = cities[nextIndex]
  var newList = cities
  newList[prevIndex] = second
  newList[nextIndex] = first
  return newList
}

1 个答案:

答案 0 :(得分:2)

是的,您的setOrder功能正在改变状态。将其粘贴以供参考:

 export function setOrder(cities, prevIndex, nextIndex){
  var first = cities[prevIndex]
  var second = cities[nextIndex]
  var newList = cities
  newList[prevIndex] = second
  newList[nextIndex] = first
  return newList
}

在该函数中,newList仍指向与<{1}}相同的相同数组。为了使其正常工作,您需要制作cities副本,并修改副本。所以,你只需要做cities

这是我在Redux文档的Immutable Update Patterns页面中谈到的问题之一(特别是“常见错误#2”)。

还有一些现有的实用程序可以冻结您的状态并检测开发中的突变。请参阅我Redux addons catalog的DevTools#Linting部分。

相关问题