在以下代码中,当我向商店添加商品时,我希望OfferList
重新呈现。 OfferList
本身不是可观察的,但是offer数组作为prop传递。
export const MerchantScreen: FC = observer(() => {
const { merchantStore } = useStores()
return (
<View>
<OfferList data={merchantStore.offers} />
<View>
<Button title={"New Offer"} onPress={() => merchantStore.addOffer()}/>
</View>
</View>
)
})
export const OfferList: FC<OfferListProps> = ({ data }: OfferListProps) => {
const renderItem = (offer: ListRenderItemInfo<any>) => {
return (
<Text>{offer.name}</Text>
)
}
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
)
}
我使用Mobx状态树。 merchantStore.addOffer()
现在所做的就是将另一个要约商品推入数组。
我尝试过的事情/发现:
例如,当我从MerchantScreen
的商店中读取信息时,通过添加
<Text>{ merchantStore.offers.toString() }</Text>
,OfferList
也将更新。我怀疑直接从父组件中的商店读取内容也会迫使子组件重新呈现。
我在这里偶然发现了一些答案,这表明可能是FlatList renderItems中缺少key
属性的问题。尝试使用key={item.id}
无济于事。另外,如您所见,我使用FlatList的keyExtractor属性。
另一个答案建议将局部状态引入这样的组件:
export const OfferList: FC<OfferListProps> = ({ data }: OfferListProps) => {
const [offers, setOfferss] = useState()
useEffect(() => {
setOffers(data)
}, [data])
const renderItem = (offer: ListRenderItemInfo<any>) => {
return (
<Text>{offer.name}</Text>
)
}
return (
<FlatList
data={offers}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
)
}
这不起作用,我的直觉是这不是它的完成方式。
如您所见,我的MerchantScreen
父组件是可观察的,而我的子组件OfferList
则不是。出乎我的意料,父组件上的observer
应该足够了。父组件应该已经在存储中检测到更改并重新呈现。子组件本身甚至不使用商店。
总体而言,眼前的问题似乎微不足道,所以我想我只是漏掉了一个重要的细节。
答案 0 :(得分:2)
MobX仅跟踪通过渲染直接访问观察者组件的数据,因此,如果您想对每个offers
做出反应,则需要在某个地方访问它们。尝试merchantStore.offers.toString()
时您确实做了一下,这就是它起作用的原因。
因此,首先需要将OfferList
设为observer
。
但是您拥有FlatList
这是本机组件,因此无法将其设为observer
。您可以做的就是访问offers
中OfferList
内的每个data={offers.slice()}
项目(基本上只是为了订阅更新),甚至可以使用MobX辅助方法toJS
{{1 }}
根据您的用例,您可能还想在data={toJS(offers)}
回调中使用<Observer>
:
renderItem