我有一个父组件ProductTest,它将状态作为事实的来源。州是一系列变体项目。这个例子简化了每个项目并有一个标题。
当更新Variant的标题时,孩子将通过父母传递的道具来调用它的处理程序回调。父母然后更新状态,然后孩子将有一个新的标题属性。
我看到的是,儿童的componentWillReceiveProps
功能会为this.props
和nextProps
显示相同的值。我认为既然这个值是由父母提供的,那么两者就会不同。
我不确定我做错了什么。
以下是父 ProductTest 组件:
import React, { Component } from 'react'
import { connect } from 'react-redux'
import axios from 'axios'
import Variant from './variants/Variant'
import { REACT_APP_API_URL, REACT_APP_SITE_KEY } from '../../../shared/vars'
import '../../../css/variants.css'
class ProductTest extends Component {
constructor(props) {
super(props)
this.state = {
variants: []
}
this.handleVariantTitleChange = this.handleVariantTitleChange.bind(this)
this.handleVariantValueChange = this.handleVariantValueChange.bind(this)
}
componentDidMount() {
this.loadData()
}
loadData() {
const apiEndpoint = 'products/some-product'
const AUTH_HEADER = { Authorization: REACT_APP_SITE_KEY }
return axios.get(REACT_APP_API_URL + apiEndpoint, { headers: AUTH_HEADER })
.then((response) => {
this.setState({ variants: response.data.product.variants })
})
.catch((err) => {
console.log("YA GOOFED BUD!", err)
})
}
handleVariantTitleChange(e, i) {
let { variants } = this.state
const { value } = e.target
variants = variants.map((item, index) => {
item.title = i === index ? value : item.title
return item
})
this.setState({ variants })
}
handleVariantValueChange(e, id) {
let { variants } = this.state
const { value } = e.target
variants = variants.map(variant => {
variant.items = variant.items.map(item => {
item.title = id === item.id ? value : item.title
return item
})
return variant
})
this.setState({ variants })
}
render() {
return (
<div>
{this.state.variants.map((variant, i) => {
return <Variant key={i}
variant={variant}
index={i}
changeVariantTitle={this.handleVariantTitleChange}
changeVariantValue={this.handleVariantValueChange}
/>
})}
</div>
)
}
}
export default ProductTest
这是儿童变体组件:
import React, { Component } from 'react'
class Variant extends Component {
componentWillReceiveProps(nextProps){
console.log(this.props, nextProps)
}
render() {
const { variant, index } = this.props
return (
<div className="variant-wrapper" data-new="new_value">
<div className="ajax-error" data-hbs-id="{{id}}"></div>
<div className="varient-item-titles">
<div className="variant-item-title">
Title
</div>
<div className="varient-attribute-titles">
<div className="variant-attribute">Value</div>
</div>
</div>
<div className="variant-item-content">
<div className="variant-label">
<input type="text" name="variant_label" value={variant.title} placeholder="Size, colour, etc."
onChange={e => this.props.changeVariantTitle(e, index)}
/>
</div>
</div>
</div>
)
}
}
export default Variant
之前
后
CONSOLE.LOG()
这两个对象是this.props和nextProps。请注意,title属性没有什么不同,因为我希望它们是。
解<!/强>
所有这些的原因是我没有正确地改变父母的状态。我想我只是在相同的内存地址处更改值,因此当它到达componentWillReceiveProps
时它已经是新值。我想......
我发现以下内容可行:
handleVariantTitleChange(e, i){
const { value } = e.target
// Immutably clone specific variant item
let variant = Object.assign({}, this.state.data.variants[i])
// Set new title to item
variant.title = value
// Set the variant to the cloned item
let variants = this.state.data.variants
variants[i] = variant
this.setState({
data: {
...this.state.data,
variants
}
})
}