我正在使用Apollo GraphQL的useMutation
钩子,我想使用onCompleted
属性执行某个任务。基本上,我想在useMutation
成功完成时执行setCheck()
钩子,并将check
状态作为道具传递给子组件
const ParentComponent = () => {
const [ check, setCheck ] = useState(false)
const [ createMessage, { loading } ] = useMutation(CREATE_MESSAGE_MUTATION, {
onCompleted: data => {
setCheck(true)
},
onError: data => {
console.log("onError Mutation", data)
}
})
return (
<KeyboardAvoidingView>
<FlatList
data={messages}
renderItem={({ item }) =>
<ChildComponent
item={item}
check={check}
/>
}
keyExtractor={item => item.id.toString()}
/>
</KeyboardAvoidingView>
)
}
问题是每次渲染父组件时,ChildComponent
渲染的次数太多,所以我使用了memo
来解决不必要的重新渲染:
const ChildComponent = ({check}) => {
console.log("check", check)
return (
<View style={styles.container} >
</View>
)
}
export default React.memo(ChildComponent)
但是,memo
以某种方式无法检测到状态check
的变化,并且根本不呈现组件。为什么memo
没有详细说明传入的道具的变化,有没有办法听听这些变化?
问题出在FlatList
上 - 它只在其data
发生变化时重新渲染其子项。由于renderItem
取决于不属于data
check
,因此您需要将其包含在extraData
道具中,以使项目在更改时重新渲染check
。有关示例,请参阅文档:https://facebook.github.io/react-native/docs/flatlist#basic-example
因此,您的FlatList
组件应该是:
<FlatList
data={messages}
renderItem={({ item }) =>
<ChildComponent
item={item}
check={check}
/>
}
keyExtractor={item => item.id.toString()}
extraData={check}
/>
check
不是状态的一部分,它是道具的一部分。 尝试将其传递给useState
钩子以使组件有状态