在 mobx 中调用动作时组件不会重新渲染

时间:2021-03-27 12:44:49

标签: reactjs mobx

我正在使用 mobx v6。 HomePage 在向下滚动到底部时调用 roomStore.fetchRooms,是的,我使用 IntersectionObserver 和 lodash/throttle 函数来实现无限滚动。

我检查了在调用 roomStore.fetchRooms 函数时调用了 loadMore,并且更新了 roomStore.homeRoomList。 Mobx 商店中的所有功能更改状态都用@action 修饰。 我想知道为什么我的 HomePage 组件没有重新渲染。

//RoomStore
export default class RoomStore extends BasicStore {
  @observable homeRoomList: GetRoomsPayload["rooms"] | null;

  constructor({root, state}: { root: RootStore, state: RoomStore}){
    super({root, state});
    makeObservable(this);
    this.homeRoomList = state?.homeRoomList ?? null;
  }

  async fetchRooms(category?: string, page:number = 0){
    const [error,response] = await this.api.GET<GetRoomsPayload>(`/room/${category}?page=${page}`);
    if(error){
      throw Error(error.error)
    }
    if(response && response.success){
      const { data } = response
      this.feedFetchHomeRooms(data.rooms);
      
      return response.data;
    }
    return Promise.resolve();
  }

  @action.bound
  feedFetchHomeRooms(rooms: GetRoomsPayload["rooms"]){
    if(rooms){
      if( this.homeRoomList) {
        this.homeRoomList = [...this.homeRoomList, ...rooms];
      }
      else {
        this.homeRoomList = rooms;
      }
    }  
  }
}

// HomePage Component
const HomePage: FC & HomePageInitStoreOnServer = ({}) => {
  const { pathname } = useLocation();
  const homeRef = useRef<HTMLUListElement>(null);
  const infiniteScrollTargetRef = useRef<HTMLDivElement>(null);
  const { roomStore } = useMobxStores();
  
  const handleLoadMore = () => {
    throttleFetch();
  }

  const throttleFetch = useCallback(throttle(() => {
    roomStore.fetchRooms()
  },500),[]);

  useInfiniteScroll({
    target: infiniteScrollTargetRef,
    cb: handleLoadMore,
  });

  useEffect(() => {
    if(!roomStore.homeRoomList){
     roomStore.fetchRooms() 
    }
  },[]);
  
  return (
      <section >
        <RoomContainer ref={homeRef}>
          {roomStore.homeRoomList?.map((room: any) => {
                return (
                  <Card
                    room={room}
                    key={room.id}
                  />
                );
              })}
        </RoomContainer>
        <InfiniteScroll targetRef={infiniteScrollTargetRef}/>
      </section>
  );
};


export default observer(HomePage);

1 个答案:

答案 0 :(得分:0)

呈现可观察数据的组件(HomePage)需要包装到观察者中。

import { observer } from 'mobx-react-lite'

const HomePage = observer(() => {
  // your code of component 
})

您可以找到更多详情in official docs here