如何使用 mobx-react-lite 使 child 组件对 mobx 中的状态变化做出反应

How to make child component reactive to state change in mobx using mobx-react-lite

我正在使用 mobx-state-tree 和 mobx-react-lite,谁能指导我找到更好的模式,

wishlist.js - 心愿单商店

import { types } from 'mobx-state-tree'

export const WishListItem = types.model('WishListItem', {
  name: types.string,
  price: types.number,
  image: "",
}).actions(self => ({
  changeName(newName) {
    self.name = newName
  },
}))

export const WishList = types.model('WishList', {
  items: types.optional(types.array(WishListItem), []),
})

root.js - 根存储

export const RootStore = types.model('RootStore', {
  counter: types.optional(Counter, { count: 0 }),
  wishList: types.optional(WishList, {
    items: [{ image: '', price: 10, name: 'Yoda' }]
  }),
})

我正在将商店更新为

setInterval(() => store.wishList.items[0].changePrice(Math.random() * 100), 500)

在我的心愿单视图中 wishlist.jsx

const WishListItem = ({ image, name, price }) => {
  return useObserver(
    () =>
      <div>
        <img src={image} />
        <h3>{name}</h3>
        <h5>{price}</h5>
      </div>
  )
}

const WishListView = ({ items }) => {
  return useObserver(
    () => <>
      {
        items.map(
          (item, key) => <WishListItem {...item} key={key} />
        )
      }
    </>
  )
}

export default () => useObserver(() => (
  <WishListView items={store.wishList.items} />
))

这里我必须在组件树的每一层使用 useObserverObserver,以使其具有反应性,有什么方法可以将反应性引用传递给 child ?

对于字符串或数字等基本类型,它工作得很好,但是对于数组或 object,我必须直接引用 parent 处的变化变量,例如 store.wishList[0].price或者在整棵树中使用 useObserver

我想将项目数组传递给 children,并更新 children 的变化,就在根部

export default () => useObserver(() => (
  <WishListView items={store.wishList.items} />
))

不再使用 useObserver childrens

更新

我发现的解决方法是解构数组,现在更改是反应性的,因为我们直接访问正在更改的变量。

export default () => useObserver(() => {
  const items = store.wishList.items.map(item => ({ ...item }))
  return <WishListView items={items} />
})

and no more useObserver at it's childrens

如果可能的话,实际上最好将所有组件标记为observer。例如,如果您将每个 Item 标记为观察者,并且其中一项更改了名称,则只有该组件会重新呈现。如果您不设置 Item 观察者,那么您的整个 List 将重新渲染,如果有很多项目或深 DOM 树,这将非常糟糕。当只有一个项目发生变化时,重新呈现整个列表也没有意义。

在这里查看解释https://mobx.js.org/refguide/observer-component.html#when-to-apply-observer

因此,您的解决方法是一种糟糕的做法,如果您无法控制子组件并且无法创建它们,则只能作为最后的手段使用 observer