Home > Blockchain >  How to specify the rendering order in React
How to specify the rendering order in React

Time:07-06

I have a .tsx file that renders two component:

export default observer(function MyModule(props: MyModuleProps) {
    ....
    return (
         <div>
             <TopPart></TopPart>
             <LowerPart></LowerPart>
         </div>
    );
});

The problem I have is that the TopPart contains lots of sub components, so it takes much longer time to render, and the LowerPart is more important and I want to render it first, but in this code, the LowerPart won't be available until the TopPart has been rendered.

What I want to do is to first render the LowerPart, then the TopPart, without changing the layout. I am wondering how I can achieve this goal properly.

CodePudding user response:

Disclaimer: this is a hack.

If the problem is server side, this is easy for react. Just throw up a placeholder while data is loading, then save it in state when loading finishes and render.

The following answer assumes this is a rendering performance problem. If it is, then you look at that rendering performance. Paginate your lists, simplify your CSS rules, profile react and see what is taking the time.

What follows may be interesting, but is probably a bad idea. React is declarative, meaning you tell the result you want and then let it crunch things to deliver that. As soon as you start telling it what order to do things in, you break that paradigm and things may get painful for you.


If you want to break up rendering you could use state to prevent the expensive component from rendering, and then use an effect to update that state after the first render, which then renders both components.

You could make a custom hook like this:


function useDeferredRender(): boolean {
  const [doRender, setDoRender] = useState(false);

  useEffect(() => {
    if (!doRender) {
      setTimeout(() => setDoRender(true), 100);
    }
  }, [doRender]);

  return doRender;
}

This hook create the doRender state, initialized to false. Then it has an effect which sets the state to true after a brief timeout. This means that doRender will be false on the first render, and then the hook will immediately set doRender to true, which triggers a new render.

The timeout period is tricky. Too small and React may decide to batch the render, too much and you waste time. (Did I mention this was a hack?)

You would this like so:

function App() {
  const renderTop = useDeferredRender();

  return (
    <div className="App">
      {renderTop ? <TopPart /> : "..."}
      <LowerPart />
    </div>
  );
}

Working example


One last time: this is probably a bad idea.

CodePudding user response:

You can make it with css:

JSX:

   <div >
     <LowerPart></LowerPart>
     <TopPart></TopPart>
   </div>

and CSS:

.reverse {
   display: 'flex';
   flex-direction: 'column-reverse'
}
  • Related