Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React SSR: Prevent client side rendering of components which are rendered on the server

I'm new to React. I'm building a site with react, react router4, react redux, etc., in which few components get rendered on the server (mostly fetching data using API calls and display them). Now my question is if I render component on the server and send rendered HTML to the client, it again gets rendered on the client (makes an API call), which I need to prevent.

I don't want to render component again if it's already rendered on the server. How can I achieve this?

Thanks

Satish

like image 979
Satish Lakhani Avatar asked Dec 22 '17 15:12

Satish Lakhani


People also ask

How do you prevent components from rendering in React?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

Does Reactjs render on client-side and server-side?

By default, your React app will be client-side rendered. This means basically, all of the source code will live in JavaScript files referenced in a single HTML file that initializes your app.

How do you prevent components from rendering after state change?

If you're using a React class component you can use the shouldComponentUpdate method or a React. PureComponent class extension to prevent a component from re-rendering.

How do I disable server-side rendering in next JS?

You can use the ssr: false object to disable server-side rendering of your dynamically imported component, as shown below. Or else, you can create a wrapper component called NonSSRWrapper and then enclose any page in that component to disable SSR.


1 Answers

I have a similar problem. I have a large table (5000 rows) rendered on the server. i don't want to send the data to the client twice (in HTML and JSON form) I came up with this solution/hack.

Before rendering the table rows, the component first checks the DOM to see if a component exists with the same id (which if pre-rendered server-side will exist), if it does then it extracts the HTML and uses that directly via dangerouslySetInnerHTML.

 renderTable() {
    debug('render table');
    const id = 'table-body';
    const html = this.getExistingHtml(id);

    if (html) {
      return <tbody id={ id } dangerouslySetInnerHTML={{ __html: html }} />;
    }

    return <tbody id={ id }>{ this.renderItems() }</tbody>;
  }

  getExistingHtml(id) {
    if (typeof document === 'undefined') return;
    const node = document.getElementById(id);
    return node && node.innerHTML;
  }

  renderItems() {
    debug('render items');
    return this.props.items.map(({ name, url }) => {
      return (
        <tr>
          <td>
            <a href={ url }>
              <div>{ name }</div>
            </a>
          </td>
        </tr>
      );
    });
  }

  shouldComponentUpdate() {
    return false;
  }

I've also coupled this with shouldComponentUpdate to prevent any renders after the initial mount.

like image 170
M.R.Safari Avatar answered Oct 26 '22 21:10

M.R.Safari