Question: I'm trying to implement a refresh button but can't get it done.

This is how my code looks like:

```
// ParentComponent.js
const ParentComponent = () => {
  const { loading, error, data } = useItems();

  return (
    <ChildComponent items={data} />
  );

  ... rest of my code that shows the data
};

// ChildComponent.js
const ChildComponent = ({ items }) => { 
  return (
    // Logic that renders the items in <li>s
    <button onClick={() => console.log('Clicking this button should refresh parent component')}
  )
};

// services/useItems.js
const useItems = () => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  useEffect(() => {
    axios
      .get(API_URL + '/counter')
      .then((response) => {
        setItems(response.data);
        setLoading(false);
      })
      .catch((error) => {
        setLoading(false);
        setError(error.message);
      });
    }, []);

    return { loading, error, data: counters };

}

```

I've tried several ways but none did the work. any helps would be truly appreciated :)

Answer: 
I don't think `useEffect` is the right mechanism here. Since it's an imperative call, nothing reactive about it, `useState` does the job just fine:

```
// ParentComponent.js
const ParentComponent = () => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  const refresh = () => {
    axios.get(API_URL + '/counter').then((response) => {
      setItems(response.data);
      setLoading(false);
    }).catch((error) => {
      setLoading(false);
      setError(error.message);
    });
  };
  useEffect(refresh, []);

  return (
    <ChildComponent items={items} refresh={refresh} />
  );

  // ... rest of my code that shows the data
};

// ChildComponent.js
const ChildComponent = ({ items, refresh }) => { 
  return (
    // Logic that renders the items in <li>s
    <button onClick={refresh}>
      Refresh
    </button>
  )
};

```
A very simple trick is to increase an integer state, let's just call it `version`, which would trigger a re-render of `<ParentComponent />` and if `useEffect` depends on `version`, it'll re-execute the callback, so you get the "refresh" effect.

```js
// ParentComponent.js
const ParentComponent = () => {
  const [version, setVersion] = useState(0)
  // when called, add 1 to "version"
  const refresh = useCallback(() => {
    setVersion(s => s + 1)
  }, [])

  const { loading, error, data } = useItems(version);

  return (
    <ChildComponent items={data} refresh={refresh} />
  );
};

// ChildComponent.js
const ChildComponent = ({ items, refresh }) => { 
  return (
    // Logic that renders the items in <li>s
    <button onClick={refresh} />
  )
};

// services/useItems.js
const useItems = (version) => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  useEffect(() => {
    axios
      .get(API_URL + '/counter')
      .then((response) => {
        setItems(response.data);
        setLoading(false);
      })
      .catch((error) => {
        setLoading(false);
        setError(error.message);
      });
    }, [version]);  // <-- depend on "version"

    return { loading, error, data: counters };

}

```