gpt4 book ai didi

javascript - 突变更新 apollo 缓存但缓存更新未反射(reflect)在 UI 中

转载 作者:行者123 更新时间:2023-11-30 19:54:48 27 4
gpt4 key购买 nike

我将 Apollo Client 与 React 结合使用,我在下面的 MWE 中概述了我的 Query/Mutation 用法。

我有一个获取用户约会的查询:

const GET_USER_APPOINTMENTS = gql`
query getUserAppointments {
getUserAppointments {
id
appointmentStart
appointmentEnd
appointmentType
status
}
}
`
// omitted code for brevity...

<Query query={GET_USER_APPOINTMENTS} fetchPolicy='network-only'>
{({ loading, error, data }) => {
if (loading) return <div>Loading...</div>
if (error) return `Error ${error}`

const appointments = data.getUserAppointments

return <BookingsBlock appointments={appointments} />
}}
</Query>

BookingsBlock 由这个 MWE 表示:

export default class BookingsBlock extends Component {
constructor (props) {
super(props)
let pastAppointments = []
let futureAppointments = []
if (props.appointments) {
// assign past and future appointments
props.appointments.forEach(appt => {
if (moment(appt.appointmentStart) < moment()) {
pastAppointments.push(appt)
} else {
futureAppointments.push(appt)
}
})
}
this.state = { pastAppointments, futureAppointments }
}

render () {
let pastAppointmentsBlock
let futureAppointmentsBlock

const EmptyBlock = (
<EmptyBookingBlock>
<h3>You have no appointments!</h3>
</EmptyBookingBlock>
)

if (this.state.pastAppointments.length) {
pastAppointmentsBlock = (
<BookingBlock>
{this.state.pastAppointments.map(appt => {
return <Appointment key={appt.id} appointmentData={appt} />
})}
</BookingBlock>
)
} else {
pastAppointmentsBlock = EmptyBlock
}

if (this.state.futureAppointments.length) {
futureAppointmentsBlock = (
<BookingBlock>
{this.state.futureAppointments.map(appt => {
return <Appointment key={appt.id} appointmentData={appt} />
})}
</BookingBlock>
)
} else {
futureAppointmentsBlock = EmptyBlock
}

return (
<div>
<h2>Your bookings</h2>
{futureAppointmentsBlock}
{pastAppointmentsBlock}
</div>
)
}
}

从上面可以看出,BookingBlockEmptyBookingBlock 是没有任何逻辑的简单样式组件。

Appointment 组件如下面的 MWE 所示:

const Appointment = props => {
const { id, appointmentStart, appointmentEnd, status } = props.appointmentData
return (
<AppointmentBlock>
<p>
<Description>Start: </Description>
<Value> {moment(appointmentStart).format('HH:mm')} </Value>
</p>
<p>
<Description>End: </Description>
<Value> {moment(appointmentEnd).format('HH:mm')} </Value>
</p>
<p>
<Description>Status: </Description>
<Value>
{status === 'Confirmed' ? (
<PositiveValue>Confirmed</PositiveValue>
) : (
<NegativeValue>{status}</NegativeValue>
)}
</Value>
</p>
<CancelAppointment
id={id}
appointmentStart={appointmentStart}
status={status}
/>
</div>
</AppointmentBlock>
)
}

同样,AppointmentBlockDescriptionValue 只是样式化的组件,没有逻辑。 CancelAppointment 是由以下 MWE 表示的组件,它通过 Mutation 取消约会:

const CANCEL_APPOINTMENT = gql`
mutation cancelAppointment($id: Int!) {
cancelAppointment(id: $id) {
id
appointmentStart
appointmentEnd
appointmentType
status
}
}
`

// code omitted for brevity...

class CancelAppointment extends Component {
constructor (props) {
super(props)
const hoursUntilAppt = moment(this.props.appointmentStart).diff(
moment(),
'hours'
)
const cancellable =
this.props.appointmentType === 'A'
? hoursUntilAppt > 72
: hoursUntilAppt > 48

this.state = {
cancelled: this.props.status === 'Cancelled',
cancellable,
firstClick: false
}
}

cancelAppointment = async (e, cancelAppointment) => {
e.preventDefault()
await cancelAppointment({
variables: { id: this.props.id }
})
}

render () {
if (!this.state.cancelled) {
if (!this.state.cancellable) {
return (
<CancelAppointmentButtonInactive>
Cancellation period elapsed
</CancelAppointmentButtonInactive>
)
}
if (!this.state.firstClick) {
return (
<CancelAppointmentButtonActive
onClick={() => {
this.setState({ firstClick: true })
}}
>
Cancel appointment
</CancelAppointmentButtonActive>
)
} else if (this.state.firstClick) {
return (
<Mutation mutation={CANCEL_APPOINTMENT}>
{cancelAppointment => {
return (
<CancelAppointmentButtonActive
onClick={e => this.cancelAppointment(e, cancelAppointment)}
>
Are you sure?
</CancelAppointmentButtonActive>
)
}}
</Mutation>
)
}
} else {
return (
<CancelAppointmentButtonInactive>
Appointment cancelled
</CancelAppointmentButtonInactive>
)
}
}
}

再次 CancelAppointmentButtonInactiveCancelAppointmentButtonActive 是按钮样式的组件。

突变按预期运行并取消了数据库上的约会。在调用突变函数后,Apollo 缓存在浏览器内存中更新以反射(reflect)约会被取消。我已经使用 Apollo 开发工具对此进行了测试。

但是,约会状态的这种变化并未反射(reflect)在 UI 中,特别是 AppointmentAppointmentBlock 中显示的状态不会更新为已取消。 CancelAppointment 按钮也没有收到对其 this.props.status 的更新,正如人们预期的那样,当通过完成的突变在缓存中更新约会时。

我最初认为这可能归结为查询/变异对象返回对象的差异,但即使在统一返回哪些字段之后,UI 也不会更新。

预约数据的数据流为Query 'GET_USER_APPOINTMENTS'BookingBlockAppointmentCancelAppointment

最佳答案

您的 BookingsBlock 组件正在将 first props 复制到自己的 state 中,因此更改 props ,由突变引起,不影响渲染状态。简单地摆脱 BookingsBlock 中的 state 会有所帮助 - 无论如何都不需要它,因为您可以轻松计算 pastAppointments render 方法中的 futureAppointments

关于javascript - 突变更新 apollo 缓存但缓存更新未反射(reflect)在 UI 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54112011/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com