我目前正在尝试获取两个对象对象,其中第二个对象具有更新值,并将更新后的值合并到第一个对象中。我写了一个函数来做这个,但我无法更新AnimatedDataWrapper中的值。但是,如果我在AnimatedDataWrapper之外运行它可以正常工作..
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import * as d3 from 'd3'
const mapNewStateToOldState = (oldState, newState) => {
Object.keys(oldState).forEach((key) => {
Object.assign(oldState[key], newState[key])
})
return oldState
}
// const mapNewStateToOldState = (oldState, newState) =>
// Object.keys(oldState).map(key => Object.assign(oldState[key], newState[key]))
const obj = { 0: { data: 1 } }
const newObj = { 0: { data: 2 } }
console.log(mapNewStateToOldState(obj, newObj)) // THIS WORKS
console.log(obj) // THIS WORKS
const AnimatedDataWrapper = (dataProp, transitionDuration = 300) => ComposedComponent =>
class extends Component {
constructor(props) {
super(props)
const data = this.props[dataProp]
this.state = Object.keys(data)
.map(label => ({ [label]: data[label] }))
.reduce((prev, curr) => ({ ...prev, ...curr }), {})
}
componentWillReceiveProps(nextProps) {
const data = this.props[dataProp]
console.log(data)
const nextData = nextProps[dataProp]
const dataKeys = this.props.dataKeys
const dataUnchanged = Object.keys(data)
.map(label => data[label] === nextData[label])
.reduce((prev, curr) => prev && curr)
if (dataUnchanged) {
return
}
d3.select(this).transition().tween('attr.scale', null)
d3
.select(this)
.transition()
.duration(transitionDuration)
.ease(d3.easeLinear)
.tween('attr.scale', () => {
const barInterpolators = data.map((...args) => {
const index = args[1]
return dataKeys.map((key) => {
const interpolator = d3.interpolateNumber(
this.state[index][key],
nextData[index][key],
)
return { key, interpolator }
})
})
return (t) => {
const newState = barInterpolators
.map(bar =>
bar
.map(({ key, interpolator }) => ({ [key]: interpolator(t) }))
.reduce((result, currentObject) => {
Object.keys(currentObject).map((key) => {
if (Object.prototype.hasOwnProperty.call(currentObject, key)) {
result[key] = currentObject[key]
}
return null
})
return result
}, {}),
)
.reduce((newObject, value, index) => {
newObject[index] = value
return newObject
}, {})
const oldState = this.state
console.log(`OLD STATE = ${JSON.stringify(oldState)}`)
console.log(`NEW STATE = ${JSON.stringify(newState)}`)
const updatedState = mapNewStateToOldState(oldState, newState) // THIS DOES NOT WORK
console.log(`UPDATED STATE = ${JSON.stringify(updatedState)}`)
this.setState(updatedState)
}
})
}
render() {
const { props, state } = this
const newData = Object.keys(state).map(val => state[val])
const newDataProps = { ...{ data: newData } }
const newProps = { ...props, ...newDataProps }
return <ComposedComponent {...newProps} />
}
}
AnimatedDataWrapper.PropType = {
dataProp: PropTypes.string.isRequired,
transitionDuration: PropTypes.number,
dataKeys: PropTypes.instanceOf(Array).isRequired,
maxSurf: PropTypes.number.isRequired,
}
export default AnimatedDataWrapper
以下是我传递给函数mapNewStateToOldState
(oldState
,newState
)的对象的样子。输出updatedState
看起来像什么。
答案 0 :(得分:2)
好的'Object.assign
将完成您正在寻找的工作,前面的对象将被其他使用相同键的对象覆盖:
var oldState = {a: 1, b: 2}
var newState = {b: 3, c: 4}
Object.assign(oldState, newState) === { a: 1, b: 3, c: 4 }
在stage-3 ecmascript you can use the spread syntax中:
var oldState = {a: 1, b: 2}
var newState = {b: 3, c: 4}
{ ...oldState, ...newState } === { a: 1, b: 3, c: 4 }