简体   繁体   中英

How do I make a client-side only component for GatsbyJS?

How do I create a component for Gatsby that will load on the client-side, not at build time?

I created this one and it renders with gatsby develop but not with the rendered server-side rendering

import React from 'react';
import axios from 'axios';
import adapter from 'axios-jsonp';

export default class Reputation extends React.Component<{}, { reputation?: number }> {
    constructor(props) {
        super(props);
        this.state = {};
    }

    async componentDidMount() {
        const response = await axios({
            url: 'https://api.stackexchange.com/2.2/users/23528?&site=stackoverflow',
            adapter
        });
        if (response.status === 200) {
            const userDetails = response.data.items[0];
            const reputation = userDetails.reputation;
            this.setState({
                reputation
            });
        }
    }

    render() {
        return <span>{ this.state.reputation?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") }</span>
    }
}

before render this component, make sure you have a window, to detect if there is a window object. I would write a hook for that:

function hasWindow() {
  const [isWindow, setIsWindow] = React.useState(false);

  React.useEffect(() => {
    
    setIsWindow(true);

    return ()=> setIsWindow(false);
  }, []);

  return isWindow;
}

In the parent component check if there is a window object:

function Parent(){
  const isWindow = hasWindow();
  if(isWindow){
    return <Reputation />;
  }
  return null;
}

If you don't want the component to be bundled in the main js file at build time, use loadable-components

Install loadable-components and use it as a wrapper for a component that wants to use a client-side only package. docs

import React, { Component } from "react";
import Loadable from "@loadable/component";

const LoadableReputation = Loadable(() =>
  import("../components/Reputation")
);

const Parent = () => {
  return (
    <div>
      <LoadableReputation />
    </div>
  );
};

export default Parent;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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