如何监听每次重新渲染 fetch-applied 组件/elmeent 的完成情况

问题描述 投票:0回答:1

问题状态: 我想使用 fetch API 将滚动事件添加到我的组件中。然而,它可以通过 Recoil 或 Context 订阅来实现,但会触发不必要的重新渲染。 (在我的情况下,我总是在使用它们后删除获取数据,因此重新渲染会导致丢失数据错误。)无论如何,是否有副作用(类似回调,不触发重新渲染)计数应用获取并在所有情况下表现出来他们已经满了。

function Foo(){
    const [data,setData] = useState(null);
    useEffect(()=>{
        fetch("somewhere")
        .then((response)=>{
            if(!response.ok){throw new Error("https error.");}
            return response.json();
        })
        .then((json)=>{
            setData(json);
        })
        .catch((error)=>{
            console.warn(error.message);
        });
    },[]);
    if(data === null){return(<div>LOADING...</div>);}
    return(
        <div id={"target-comp"}>
            {data}
        </div>
    );
}

function initSomthingAboutDom(){
    //this function should be called only when every render is completed!
    const targetComp = document.getElementById("target-comp");
    //something about DOM control....
}
html reactjs dom jsx
1个回答
0
投票

我取得了一些成就!

  1. 我将附加组件
    FetchProvider
    添加到包含 fetch 的组件的末尾。安装后,
    FetchProvider
    可以使用 Recoil 和
    useEffect
    相互通信。
  2. 由于这个附加组件确保它们安装在成功获取的返回内部,我可以使用它作为计数单位,排除不必要的重新渲染。
  3. 但是即使
    initScroller
    已满,我也无法立即调用
    FetchListener
    ,因为它们仍在渲染中。我无法访问 DOM。所以,我用了
    setTimeout
  4. 为了实现最快、最安全地使用
    setTimeout
    ,我还在根元素内部添加了另一个
    fetchProvider
    。这可以确保
    FetchListener
    在渲染的最后一步表现。这样,我可以缩短时间间隔,让这个逻辑更安全。

FetchProvider 和 FetchListener 的定义

const fetchAtom = new atom({key: "fetch", default: [false,false,false]});
export function FetchProvider({index}){
    const [fetch,updateFetch] = useRecoilState(fetchAtom);
    useEffect(()=>{
        const newFetch = [fetch[0],fetch[1],fetch[3]]; newFetch[index] = true;
        updateFetch(newFetch);
    },[]);
    return(<></>);
}
export function FetchListener(){
    const fetch = useRecoilValue(fetchAtom);
    useEffect(()=>{
        console.log(fetch);
        if(fetch.some((e)=>{return e === true;})){
            setTimeout(()=>{
                initScroller();
            },100);
        }
    },[fetch]);
}

它们的用途

//SomeReactComp()
fetch bla.. bla
if(dataFromFetching === null){return(<div>LOADING</div>)}
return(
  <>
    <div className={"skill"}>
      {topImgs}<div>{bottomImgs}</div>
        </div>
    <FetchProvider index={1}/>
    </>
);

//RootComp
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <RecoilRoot>
      <FetchListener/>
      <App/>
      <FetchProvider index={2}/>
    </RecoilRoot>
  </React.StrictMode>
);

© www.soinside.com 2019 - 2024. All rights reserved.