我有一个反应组件ReorderComponent,它呈现一个由redux商店传递的列表。 我将列表包装在“react-reorder”的重新排序组件中,当用户更改列表的顺序时,我将dipatch函数作为更新商店的道具传递。
这个步骤已成功完成,因为我可以看到商店更新,主容器接收到新状态,并带有重新排序的列表。
但是,当状态发生变化时,我的ReorderComponent不会更新它的道具。
结构如下:
-RequestContainer.js
- 连接到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
在这张图片中,我们可以看到在状态改变之后,哑组件没有更新它的道具,因为它没有记录任何东西。
减速机:
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
}
答案 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部分。