0

I've got a small React problem, the answer of which I haven't been able to find so far.

I have a page with a Textfield and two Buttons. When the left button is clicked, the input of the textfield should be stored in the cache. When the right one is clicked the textfield's value should be set to the cache's value.

I wrote everything and tried to test it, but I got an unexpected exception: "Warning: Expected 'onClick' listener to be a function, instead got a value of 'object' type."

I read the official documentation and this SO post, and it feels like my code should work, but I'm missing something. I tried making them into separate consts and referencing those (onClick={cacheData}), but it also didn't work.

Code:

imports [...]

const OfflineTextField = (onChange) => {
  return (
    <TextField onChange={onChange} multiline={true}>
    </TextField>
  );
};

const SaveInputButton = (onClick) => {
  return (
    <Button onClick={onClick} color="primary"> // I pass the onClick method
      Save text
    </Button>
  );
};

const LoadInputButton = (onClick) => {
  return (
    <Button onClick={onClick} color="primary">  // I pass the onClick method
      Load text
    </Button>
  );
}

const PocOfflineScreen = () => {
  let [input, setInput] = useState<string>("");
  let cacheName = 'testrapport';
  let url = 'http://localhost:3000';
  
  const onInputChange = (text: React.ChangeEvent<HTMLInputElement>) => {
    setInput(text.target.value);
  };

  return (
    <div>
      {OfflineTextField(onInputChange)}
      <br />
      <SaveInputButton onClick={() => {
        if ('caches' in window) {
          caches.open(cacheName).then((cache) => {
            cache.put(url, new Response(JSON.stringify(input)));
            alert('Data added to cache');
          });
        };
      }}/>   
      <LoadInputButton onClick={() => { // React doesn't see this as a function, but as an object
        if ('caches' in window) {
          caches.open(cacheName).then((cache) => {
            cache.match(url).then((response: Response | undefined) => {
              if (response === undefined) {
                alert("Error: No cache found.");
              } else {
                response.json().then(data => {
                  setInput(data);
                });
              };
            });
          });
        };
        }}/>
    </div>
  );
};
JasperMW
  • 465
  • 3
  • 7
  • 22
  • Are you not accessing the onClick prop correctly in your button components? Shouldn't it be `this.props.onClick`? – Jake Stewart Apr 05 '23 at 14:55
  • @JakeStewart I think I do, if I change `` to ``, it says "this" may be undefined and doesn't compile. They're not 'true' objects after all, right? – JasperMW Apr 05 '23 at 15:07

1 Answers1

1

Props you put into SaveInputButton is an object looks like

{
  onClick: () => {
    if ("caches" in window) {
      caches.open(cacheName).then((cache) => {
        cache.put(url, new Response(JSON.stringify(input)));
        alert("Data added to cache");
      });
    }
  }
}

So you may either

  1. use props.onClick to get the function
const SaveInputButton = (props) => {
  return (
    <Button onClick={props.onClick} color="primary"> // I pass the onClick method
      Save text
    </Button>
  );
};
  1. or destructing onClick function from the props
const SaveInputButton = ({ onClick }) => {
  return (
    <Button onClick={onClick} color="primary"> // I pass the onClick method
      Save text
    </Button>
  );
};

Same on LoadInputButton.

Lynn C.
  • 191
  • 6