ReactNode.jsJavaScript

Gatsby-Ghost Suche: Redis und RediSearch - Teil 3

Die React Komponente des Gatsby Layouts den neuen Gegebenheiten anzupassen ist nicht aufwendig und schnell erledigt.

Im ersten Blog Post haben wir das "gatsby-plugin-search" um eine Redis Schnittstelle erweitert und im Zweiten haben wir uns um den serverseitigen Code gekümmert. Nun bleibt lediglich über der React Suchkomponente für unser Gatsby Layout zu erklären wie sie die Suchergebnisse vom Server bekommt.

React Komponente

An der Suchkomponente müssen wir nicht sehr viel machen. Vorab können wir in der ./gatsby-config.js das Plugin gatsby-plugin-workerize-loader enfernen.

./gatsby-config.js
/* ... */
	plugins: [
		/* ... */
		{ resolve: `gatsby-plugin-sharp` },
		{ resolve: `gatsby-transformer-sharp` },
		// { resolve: `gatsby-plugin-workerize-loader` },
		/* ... */
	]
}

Entfernen des Web Workers

Den import für den Webworker sowie die Funktion, die ihn instanziert, werden nicht mehr benötigt und können gelöscht oder auskommentiert werden.

./src/components/search/index.js
import React, {useRef, useEffect, useState} from 'react';
import PropTypes from 'prop-types';
import {Link} from 'gatsby';
import {MdSearch, MdClose} from 'react-icons/md';
//import SearchWorker from '../../utils/search.worker.js';

const Search = ({active, scrolling, onClick, maxResults = 10}) => {
  const [result, setResult] = useState([]);
  const [style, setStyle] = useState({});
  const containerElement = useRef(null);
  const inputElement = useRef(null);
  // const searchWorkerRef = useRef(null);

  let lastScrollY = 0;

  /*
    function getSearchWorker() {
      if(!searchWorkerRef.current) {
        searchWorkerRef.current = new SearchWorker();
      }
      return searchWorkerRef.current;
    }
  */

/* ... */

Das onChange Event anpassen

In der Funktion vom onChange Event des Input Elements haben wir einige Zeilen zu ändern. Den Web Worker brauchen wir nicht mehr, weil die Fetch API standardmäßig asynchron ausgeführt wird. Da der Server ein Objekt anstelle eines Arrays zurückgibt, erstellen wir mit Object.entries() ein Array mit Key-Value-Paaren aus dem Objekt und speichern das in dem result[] Array.

./src/components/search/index.js
/* ... */

async function change() {
  try {
    const query = encodeURIComponent(inputElement.current.value.toLowerCase());

    if(query.length > 1) {
      // const results = await getSearchWorker().search(query, maxResults);
      const res = await fetch(`https://michm.de/suche?q=${query}`);
      const results = await res.json();

      // if(results.length > 0) {
      // setResult(results);

      if(results !== undefined && typeof results == 'object') {
        setResult(Object.entries(results));
      }
      else {
        setResult([]);
      }
    }
    else {
      setResult([]);
    }
  }
  catch(error) {
    console.error(error.message);
  }
}

/* ... */

JSX im return

Da nun unser result[] Array ein anderen Aufbau als zuvor hat, passen wir die Stelle an an der wir durch ihn iterieren.

./src/components/search/index.js
/* ... */

/*
  result.map((post) => {
    return (
      <li key={post.id}><Link to={`/${post.slug}`}>{post.title}</Link></li>
    )
  })}
*/

return (
  <>
    /* ... */
    {result.length > 0 &&
      <div className="result-container" style={style}>
        <ul>        
          {result.map(([slug, title], i) => {
            return (<li key={i}><Link to={`/${slug}`}>{title}</Link></li>)
          })}
        </ul>
      </div>
    }
    /* ... */
  </>
);

/* ... */

Darstellung im Browser

image

Weitere Blog Posts aus dieser Serie

  1. Gatsby-Ghost Suche: React Komponente
  2. Gatsby-Ghost Suche: Webworker
  3. Gatsby-Ghost Suche: Content indizieren
  4. Gatsby-Ghost Suche: Redis und RediSearch (Teil 1)
  5. Gatsby-Ghost Suche: Redis und RediSearch (Teil 2)
  6. Gatsby-Ghost Suche: Redis und RediSearch (Teil 3)