繁体   English   中英

如何在 function 调用之外重新渲染 React 组件

[英]How to re-render React Component when outside function call

我创建了一个 class object 来存储帖子列表。 更新帖子时,注册了 Pub-Sub 模式订阅 function。

class PostLoad extends PubSub { 
  store = [];
  constructor (){
    super();
    this.connectSocket = connectSocket(this.projectUid, async (type, post) => {
      console.log('Socket HOOK', type, post);
      if (type === 'insert') await this.newPostPush(post);
      if (type === 'update') {
        const {deleted} = post;
        if (deleted) await this.deletePostInStore(post.id);
      }
    });
  }
  async postLoad () {
   // ...API LOAD
   const value = axios.get('');
   this.store = value;
  }
  private async newPostPush(post: HashsnapPostItem) {
    if (post.type === 'video') return;
    const storeItem = {...post, img: await loadImage(post.url)} as HashsnapPost;
    this.store.unshift(storeItem);
    if (this.store.length > this.limit) this.store.splice(this.limit);
    this.emit('insert', {post: storeItem, store: this.store});
  }
  private deletePostInStore(targetId: number) {
    this.store.push(...this.store.splice(0).filter(({id}) => id !== targetId));
    this.emit('delete', {postId: targetId, store: this.store});
  }
}

React 组件执行 Pub-Sub 中注册的事件,当帖子更新时,状态值发生变化,但没有变化。

const PostList = () => {
  const [postList, setPostList] = useState([]);
  const postLoad = store.get('postLoad'); // PostLoad Class Object

  useEffect(() => {
   setPostList(postLoad.store);
  }, []);

  postLoad.on('delete', (payload) => {
    setPostList(postLoad.store);
  })

  postLoad.on('insert', (payload) => {
    setPostList(postLoad.store);
  })

  return <div>
   {postList.map((post, i) => {
     return <div key={`post-${i}`}></div>
   })}
  </div>
}

我想要的是当执行 Pus-Sub 事件时,状态值发生变化并重新渲染。

 async postLoad () { //...API LOAD- axios is a async func, need await this const value = await axios.get(''); this.store = value; } postLoad.on('delete', (payload) => { setPostList(postLoad.store); }) postLoad.on('insert', (payload) => { setPostList(postLoad.store); }) // thest two register on postLoad will repeat many times, just use hook useEffect, if postLoad always change, useRef, so the right code is below const PostList = () => { const [postList, setPostList] = useState([]); const {current: postLoad} = useRef(store.get('postLoad')); useEffect(() => { setPostList(postLoad.store); postLoad.on('delete', (payload) => { setPostList(postLoad.store); }) postLoad.on('insert', (payload) => { setPostList(postLoad.store); }) return () => { // please unregister delete and insert here } }, [postLoad]); return <div> {postList.map((post, i) => { return <div key={`post-${i}`}></div> })} </div> }

暂无
暂无

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

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