[英]Change in state propagation to props stops at react-redux-connected component
状态保存在MyPayments组件中(它是本地状态-即使您可以看到连接的组件,我也很少使用Redux)。
它具有以下结构:
{
payments: [
{
amount: 400.00,
status: pending
//...
},
{
amount: 200.00,
status: approved
//...
}
]
}
payments
数组作为道具传递给子组件(连接的ClientPayments
)-您可以在上面的屏幕截图中看到它。 我相信连接的组件将其进一步传递给ClientPayments
组件。 但...
在某个时间点,成功的AJAX请求后,其中一项付款的状态属性可能会更改。 这样做时,我想更改如何在ClientPayments
组件内呈现付款。 但是,当我检查React devtools中ClientPayments
组件的道具时,我可以看到更改后的付款在这里仍然具有相同的状态。 尽管Connect(ClientPayments)
组件的付款Connect(ClientPayments)
正确更新。
MyPayments.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { camelCaseKeysDeep } from './Utils'
import ClientPayments from './ClientPayments'
class MyPayments extends Component {
constructor () {
super()
this.state = {
payments: [],
isLoading: false,
}
this.updatePaymentStatus = this.updatePaymentStatus.bind(this)
}
componentDidMount () {
this.setState({
isLoading: true,
})
axios.get(`/api/users/${this.props.userId}/payments`, {
params: {
includes: [
'bankAccount',
],
},
}).then(response => {
const payments = response.data
const camelCasedPayments = camelCaseKeysDeep(payments)
this.setState({
payments: camelCasedPayments,
isLoading: false,
})
}).catch((thrown) => {
console.log(thrown)
this.setState({
isLoading: false,
})
})
}
updatePaymentStatus(paymentId, newStatus) {
this.setState((prevState) => {
let payments = prevState.payments
const paymentIndex = _.findIndex(payments, (payment) => (payment.id === paymentId))
payments[paymentIndex].status = newStatus
return {
payments: payments
}
})
}
render () {
const {payments, isLoading} = this.state
const userId = this.props.userId
const expandedId = parseInt(this.props.match.params.id)
return (
<div>
<h2>My payments</h2>
<div className='panel panel-default'>
<ClientPayments payments={payments} isLoading={isLoading}
expandedId={expandedId} userId={userId} onPaymentStatusChange={this.updatePaymentStatus}/>
</div>
</div>
)
}
}
const mapStateToProps = state => {
return {
userId: state.user.id,
}
}
export default connect(mapStateToProps)(MyPayments)
ClientPayments.js
import React, { Component } from 'react'
import { Button, Table } from 'react-bootstrap'
import { LinkContainer } from 'react-router-bootstrap'
import { connect } from 'react-redux'
import Loader from './Loader'
import PaymentRow from './PaymentRow'
import withFileUpload from './withFileUpload'
import SingleUploader from './SingleUploader'
import BankAccountTable from './BankAccountTable'
import StatusIndicator from './StatusIndicator'
import PaymentStatusAlert from './PaymentStatusAlert'
class ClientPayments extends Component {
constructor (props) {
super(props)
this.SingleUploaderWithFU = withFileUpload(
SingleUploader,
'file',
)
this.handleSwiftCopyUploaded = this.handleSwiftCopyUploaded.bind(this)
}
handleSwiftCopyUploaded (paymentId) {
this.props.dispatch({
type: 'NOTIFY',
status: 'success',
message: 'A new SWIFT copy has been uploaded',
})
axios.put(`/api/payments/${paymentId}/status`, {
'status': 'pending',
}).then(() => {
this.props.onPaymentStatusChange(paymentId, 'pending')
})
}
render () {
const {payments, isLoading, expandedId} = this.props
return (
<Table responsive striped hover fill>
<thead>
<tr>
<th />
<th>Created</th>
<th>Amount</th>
<th>Bank</th>
<th>Actions</th>
</tr>
</thead>
{
payments.map((payment) => {
const storedSwiftCopy = payment.swiftCopyNameOrig !== null ? {
name: payment.swiftCopyNameOrig,
preview: payment.swiftCopyFullPath,
thumb: payment.swiftCopyThumbPath,
} : null
return (
<PaymentRow key={payment.id} payment={payment}
initiallyExpanded={expandedId === payment.id}>
<div>
<StatusIndicator status={payment.status}/>
<PaymentStatusAlert status={payment.status} rejectionMsg={payment.rejectionMsg}/>
<h4>Bank account details</h4>
<BankAccountTable bankAccount={payment.bankAccount}/>
<h4>Swift copy upload</h4>
<this.SingleUploaderWithFU initFile={storedSwiftCopy}
autoUpload
postUrl={`/api/payments/${payment.id}/swift-copy`}
onFileUploaded={() => this.handleSwiftCopyUploaded(payment.id)}/>
</div>
</PaymentRow>
)
})
}
{
isLoading ? (
<tbody>
<tr>
<td colSpan={5}>
<div className='vertical-spacer'>
<Loader />
</div>
</td>
</tr>
</tbody>
) : (
payments.length === 0 && (
<tbody>
<tr>
<td colSpan={5}>
<div className='vertical-spacer'>
<div>
<p className='text-center'>You have no payments yet.</p>
<p className='text-center'>
<LinkContainer to='/payments/new'>
<Button bsStyle='primary'>Receive one</Button>
</LinkContainer>
</p>
</div>
</div>
</td>
</tr>
</tbody>
)
)
}
</Table>
)
}
}
export default connect()(ClientPayments)
为什么状态更改没有传播? 我该如何解决?
您可以在此处找到一些相关主题: React:为什么在prop更改时子组件不会更新
另外,请尝试打印在componentShouldUpdate上获得的数据,您可以在这里找到它: https : //facebook.github.io/react/docs/react-component.html#shouldcomponentupdate
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.