微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决在 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);

解决方法

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。