简体   繁体   English

MobX状态树-模型数组不会触发更新

[英]MobX state tree - array of models doesn't trigger update

I have following model: 我有以下模型:

 const AnotherModel = types.model({
    foo: types.string
 });

 export const SomeCollectionModel = types
     .model({
         data: types.array(AnotherModel),
     })
     .views((self) => ({
         getData: () => self.data,
     }))
     .actions((self) => ({
         fetchData: flow(function* fetchData() {
             try {
                 const data =
                     yield service.fetchData();
                 self.data.replace(
                     data.map((f) => AnotherModel.create(f)),
                     // Using plain json instead of create does the same
                 );
             } catch (err) {
                 console.error(err);
             }
         })
    }));

Then I have two React components, which I compose with inject and observer . 然后,我有两个React组件,分别由injectobserver

Parent one (view/page): 父级之一(视图/页面):

compose(
    inject((states) => ({
        fetchData: () =>
            states.myModel.fetchData(),
    })),
    observer,
)

Child one: 孩子一:

compose(
    inject(states => ({
        data: states.myModel.getData()
    })),
    observer
)

I have a re-rednering problem. 我有一个重新调整的问题。 Initially child component doesn't render anything. 最初,子组件不呈现任何内容。 In the meantime data is fetched (action triggers itself). 同时,将获取数据(动作触发自身)。 However data is not updated in child. 但是,数据不会在子级中更新。 componentWillReact doesnt trigger. componentWillReact不会触发。 After changing routes (rerender by router) view gets updated 更改路由(通过路由器渲染)后,视图将更新

Do you have any idea? 你有什么主意吗? I'm stuck for hours. 我被困了几个小时。

  1. You don't need to create a view to access your raw data, you can use the prop directly: 您无需创建视图即可访问原始数据,可以直接使用prop:
inject(states => ({
  data: states.myModel.data
}))
  1. You don't need to use observer if you use inject . 如果使用inject则无需使用observer MyComponent will observe what's inside the inject just fine: MyComponent将观察注入内部的一切:
inject(states => ({
  data: states.myModel.data
}))(MyComponent)
  1. In this case, you are observing the array, which is a reference. 在这种情况下,您正在观察作为参考的数组。 If you update the items of the array, the array itself doesn't change so MyComponent is not re-rendered. 如果更新数组的项目,则数组本身不会更改,因此不会重新呈现MyComponent。 You could observe the array length, that way if the length changes, MyComponent is re-rendered, but it's only useful when you add or remove items from the array: 您可以通过这种方式观察数组的长度,如果长度发生变化,则将重新渲染MyComponent,但这仅在您添加或删除数组中的项目时才有用:
inject(states => ({
  data: states.myModel.data,
  length: states.myModel.data.length
}))(MyComponent)
  1. Finally, if want to observe changes to the items of the array even if the length doesn't change, you need to observe the items internally: 最后,如果即使长度不变也要观察数组项的变化,则需要在内部观察项:
inject(states => ({
  data: states.myModel.data,
  length: states.myModel.data.length
}))(MyComponent)

const MyComponent = ({ data }) => (
  <div>{data.map(item => (
    <MyDataItem item={item} />
  ))}
  </div>
)

inject((states, props) => ({
  foo: props.item.foo
}))(MyDataItem)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM