Exploring the capabilities of searching through a Shopify storefront using GraphQL within a Remix React

As a beginner in Remix React projects, I am currently struggling to grasp the project's structure. My goal is to create a SearchBar Component within the Header that displays the first 10 products based on user input. Below is the code snippet of my Search Component within the Header Component:

function SearchForm() {
  const SEARCH_PRODUCTS_QUERY = `
  query SearchProducts($query: String!) {
    products(query: $query, first: 10) {
      edges {
        node {
          id
          title
          handle
          description
        }
      }
    }
  }
`;
  const [searchTerm, setSearchTerm] = useState('');
  const [searchResults, setSearchResults] = useState([]);
  function handleSearch() {
    // console.log('handle search', searchTerm);
  }
  return (
    <div>
      <input
        type="text"
        placeholder="search"
        value={searchTerm}
        onChange={(event) => setSearchTerm(event.target.value)}
      />
      <button type="button" onClick={handleSearch}>
        Search
      </button>
      <ul>
        {searchResults.map((product) => (
          <li key={product.node.id}>{product.node.title}</li>
        ))}
      </ul>
    </div>
  );
}

I have simply integrated this into the Header Component. However, I am unsure whether to manage the query here or if I require API endpoints for the response body. How can I properly implement the handleSearch function to achieve functionality? Should the query be contained within this component?

Answer №1

If you're looking to enhance your web development skills, consider utilizing the innovative Full Stack Component pattern. Take a look at more information here:

To implement this pattern, start by creating a resource route and then exporting a loader function that executes the query and retrieves the results.

Next, export your SearchForm component which will interact with the resource endpoint and display the user interface accordingly.

Finally, import the SearchForm component into your Header to utilize it within your project.

// routes/resource.search-form.tsx

export async function loader({ request }: DataFunctionArgs) {
  const url = new URL(request.url)
  const query = url.searchParams.get('query')
  const results = await doSearch(query)
  return json(results)
}

export function SearchForm() {
  const fetcher = useFetcher<typeof loader>()

  return (
    <div>
      <fetcher.Form method="get" action="/resource/search-form">
        <input type="text" name="query" placeholder="search" />
        <button>Submit</button>
      </fetcher.Form>
      {fetcher.data && (
        <ul>
          {fetcher.data.map((product: any) => (
            <li key={product.node.id}>{product.node.title}</li>
          ))}
        </ul>
      )}
    </div>
  )
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The binding element 'params' is assumed to have a type of 'any' by default

I encountered an issue The binding element 'params' implicitly has an 'any' type. Below is the code snippet in question: export default function Page({ params }) { const { slug } = params; return ( <> <h1>{s ...

Create a script that will split a single block of text into separate sections based on predefined conditions

I have developed a script using Tampermonkey which modifies a value on a specific webpage. On the webpage, there is an input box with the value "FPPUTHP1100000". This value is a material code with the following structure: F represents FRESH PPUTHP repr ...

The Material-UI Button Component is experiencing issues after being deployed on Github Pages and is not functioning as expected

<Button href={node.slug}> <span>Read more</span> </Button> Essentially, the code above represents a button inside a Card component. If further clarification is needed, please don't hesitate to ask. The variable node.slug res ...

How to pass selected rows from Material-Table in React.js to another page

Is there a way to redirect to another page while passing selected row data as a prop? I am using material-table and I need to transfer the selected rows data to another page upon clicking the "Export" button, so that I can utilize the data in generating a ...

Using conditional rendering to set an icon in a ChipField component in React Admin

One feature in my React Admin App is a Datagrid with a ChipField displaying a text property. I want to enhance this by adding an icon to the ChipField using the icon prop, which should change based on the text value. This is my current approach: expor ...

Requires a minimum of two page refreshes to successfully load

Our website is currently hosted on Firebase. However, there seems to be an issue as we have to refresh the website at least twice in order for it to load when visiting www.website.com. Update: We are unsure of what could be causing this problem. W ...

Is there a way to ensure that the navigation tabs in Tailwind always display a scroll bar?

My navigation bar contains multiple tabs that require scrolling to be fully visible. On the initial load, users may not realize they can scroll to see additional tabs. To address this issue, I want to always display a scrollbar on the navigation bar. ...

An issue with the updating process in React Native's useState function

I am currently facing a challenge with an infinite scroll listview in react native. I have created a calendar list that needs to dynamically change based on the selected company provided as a prop. The issue arises when the prop (and the myCompany state) a ...

method for sorting labels in Select element in ReactJS

Hey there, I'm facing an issue with the code snippet available here. I would really appreciate it if you could assist me in resolving this problem. This is the code: import React from "react"; import { Select } from "antd" ...

Utilizing React Ag Grid with custom Material design elements

Is it possible to apply material theme based classes to Ag Grid rows? Here is the scenario I am facing. Thank you in advance. Material Styles const customStyles = makeStyles((theme) => ({ actionIcon: { '& svg': { f ...

Is localStorage.getItem() method in NextJS components behaving differently?

I'm working on my nextjs application and I wanted to utilize the power of localstorage for storing important data throughout my app. Within the pages directory, specifically in the [slug].tsx file, I implemented the following logic: export default fu ...

Material-ui does not support autocomplete functionality

I encountered an issue with my JSX file, as I received the following error: Uncaught ReferenceError: AutoComplete is not defined Upon reviewing the code, everything seems correct. Here is the snippet of the code: import React, {Component} from 'r ...

What is the best way to access the variant value within the content of SnackbarProvider component

Currently, I am utilizing the notistack library to display snackbars in my application. To personalize the content of the snackbar, I am using the content property of the snackbar. My goal is to determine whether the message variant is success, warning, or ...

Tips for rearranging objects within a jsPDF document to prevent vertical overlap when a table grows in size

I am new to React and Javascript. I have been struggling to find a solution to my issue while trying to create a .pdf document for a customer invoice using "jsPdf" along with its plugin "jspdf-autoTable". So far, everything is being generated correctly by ...

The perpetual loop in React context triggered by a setState function within a useEffect block

I'm experiencing an endless loop issue with this context component once I uncomment a specific line. Even after completely isolating the component, the problem persists. This peculiar behavior only manifests when the row is discounted and the browser ...

"Utilizing the Image onLoad event in isomorphic/universal React: Activating event registration once the image has been

When a page is rendered isomorphically, the image can be downloaded before the main script.js file. This means that the image may already be loaded before the react register's the onLoad event, resulting in the event never being triggered. script.js ...

Reactjs, encountering a hitch in utilizing material UI: Incompatible hook call detected

As a newcomer to React, I decided to incorporate Material UI components into my project. After installing the components locally using npm install and importing them into my project, I encountered an error when trying to run start: Error: Invalid hook call ...

Is it feasible to incorporate an external library as a script within a class or functional component in React?

Welcome and thank you for taking the time to read this question! I am currently working on a project where I need to load a TIFF image. After researching, I found a library that can help with this task: https://github.com/seikichi/tiff.js There is also ...

What exactly occurs when a "variable is declared but its value is never read" situation arises?

I encountered the same warning multiple times while implementing this particular pattern. function test() { let value: number = 0 // The warning occurs at this line: value is declared but its value is never read value = 2 return false } My curi ...

Tips for minimizing the height of the Material Toolbar in Material-UI

I'm looking to customize the height of the toolbar in Material-UI to make it smaller Although I checked out How do I change the Material UI Toolbar height?, I am still struggling with this issue Increasing the height above 50 seems to work, but redu ...