skip to Main Content

I am attempting to convert the following class component into a function component.

I have made good progress (I believe) but I am running into issues converting the various references of setState used in the class component into useState for use in the function component.

Class Component that Needs Converting:

import React from "react";
import { EmptyState, Layout, Page } from "@shopify/polaris";
import { ResourcePicker } from "@shopify/app-bridge-react";

class MyComponent extends React.Component {
  state = { open: false };
  render() {
    return (
      <Page>
        <ResourcePicker
          resourceType="Product"
          showVariants={false}
          open={this.state.open}
          onSelection={(resources) => this.handleSelection(resources)}
          onCancel={() => this.setState({ open: false })}
        />
        <Layout>
          <EmptyState
            heading="Discount your products temporarily"
            action={{
              content: "Select products",
              onAction: () => this.setState({ open: true }),
            }}
          >
          </EmptyState>
        </Layout>
      </Page>
    );
  }
  handleSelection = (resources) => {
    console.log(resources);
  };
}

export default MyComponent;

Function Component Code (Thus Far):

import React, { useState, useCallback } from "react";
import { EmptyState, Layout, Page } from "@shopify/polaris";
import { ResourcePicker } from "@shopify/app-bridge-react";

function MyComponent(props) {
  const [resourcePicker, setResourcePicker] = useState({ open: false });
  const handleToggleResourcePicker = useCallback(
    () => setResourcePicker((active) => !active),
    []
  );

  return (
    <Page>
      <ResourcePicker
        resourceType="Product"
        showVariants={false}
        open={setResourcePicker}
        onSelection={(resources) => handleSelection(resources)}
        onCancel={() => setResourcePicker}
      />
      <Layout>
        <EmptyState
          heading="Discount your products temporarily"
          action={{
            content: "Select products",
            onAction: () => setResourcePicker,
          }}
        ></EmptyState>
      </Layout>
    </Page>
  );
}

const handleSelection = (resources) => {
  console.log(resources);
};

export default MyComponent;

Can someone help set me in the right direction here? Thanks!

2

Answers


  1. You are overly complexifying things. You don’t need to put objects inside useState unless required. useCallback is beneficial if your function changes too much and performs expensive computations, in your case, it’s not required.

    const [resourcePicker, setResourcePicker] = useState({ open: false });
      const handleToggleResourcePicker = useCallback(
        () => setResourcePicker((active) => !active),
        []
      );
    

    can be changed into

    const [resourcePicker, setResourcePicker] = useState(false);
    const handleToggleResourcePicker = () => {
      setResourcePicker(active => !active)
    }
    

    Rest I would suggest you to read React Docs

    Login or Signup to reply.
  2. The issue is this line:

    onAction: () => setResourcePicker,
    

    The function is not being called and you need to pass a value in. In order to match the functionality of the class version, it should be:

    onAction: () => setResourcePicker({ open: true }),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search