我有一个react-redux应用程序,当子组件位置在状态更改中发生变化时,我正在使用react-transition-group进行转换。但是,如果我的redux状态对象的顺序改变了,组件将被卸载然后重新安装,而不是更新。这样可以防止组件平稳过渡到新位置。有没有解决此问题的方法而又不引入新状态?
我的父组件如下所示:
class ParentComponent extends Component {
...
render() {
return (
<div>
<div>
<CSSTransitionGroup>
<ChildComponents childComponentsToRender=
{this.props.someChildComponents}/>
<CSSTransitionGroup/>
</div>
</div>
)}}
ChildComponents看起来像这样:
export default function ChildComponents(props) {
const childrenToReturn = _.map(props.childComponentsToRender,
(childComponent) =>
<ChildComponent
key={childComponent.uniqueId}
position={childComponent.position} .../>
return (
<Fragment>
{childrenToReturn}
</Fragment>
)
}
一个单独的ChildComponent看起来像这样:
export default function ChildComponent(props) {
return (
<div style={{transform: `translate(${props.position.x}px,
${props.position.y}px)`}}>
</div>
)
}
我呈现组件的redux状态如下:
{
...,
someChildComponents: {
childComponent1: {
id: someUniqueId,
position: {x: int, y: int}
},
childComponent2: {
id: someUniqueId,
position: {x: int, y: int}
},
...
},
...
}
例如,如果调度了某个动作并且状态从以下更改,则会发生此问题:
{
someChildComponents: {
childComponent1: {
id: someUniqueId,
position: {x: 100, y: 100}
},
childComponent2: {
id: someUniqueId,
position: {x: 200, y: 200}
}
}
}
收件人:
{
someChildComponents: {
childComponent2: {
id: someUniqueId,
position: {x: 300, y: 300}
},
childComponent1: {
id: someUniqueId,
position: {x: 150, y: 150}
}
}
}
答案 0 :(得分:0)
如果需要关联元素的特定位置,则最好需要数组而不是对象。但是我不建议将someChildComponents
转换为数组。在大多数情况下,存储不同的数据时,对象优先于数组。
您可以基于someChildComponents
对象动态创建数组,例如使用selectors。您唯一需要的是someChildComponents
对象中的一些唯一标识符,该标识符可用于对数组进行排序。
这是示例代码
const getChildrenComponents = state => state.someChildComponents;
export function makeArrayFromChildrenComponents() {
return createSelector(
[getChildrenComponents],
(ChildrenComponents) => (
Object.keys(ChildrenComponents).map(key => ChildrenComponents[key])
.sort((e1, e2) => {
if (e1.id === e2.id) return 0;
return e1.id < e2.id ? -1 : 1;
});
)
)
}
然后使用它为ParentComponent
这样的子组件提供稳定的数组
const makeMapStateToProps = () => {
const getChildrenComponentsArray = makeArrayFromChildrenComponents();
const mapStateToProps = (state) => ({
ChildrenComponents: getChildrenComponentsArray(state)
// ... other mapped props
});
return mapStateToProps;
}
选择器将在状态更改时更新ChildrenComponents
。但是数组本身将拥有相同顺序的元素。
您还可以查看React用来决定是构建新树还是保留现有树的diffing algorithm。