I just recently upgraded our FE Stack to React 16.8 which added React Hooks. And I immediately learned something about `useEffect`. At first, I was a little confused by it and got into an infinite loop situation.

useEffect(() => {
    getTableData()
});

After a quick Google, I blindly followed a StackOverflow example and added an empty array as the 2nd param to useEffect.

This stopped my infinite loop, but then as the state changed like sortCol or sortDir, getTableData() was never called.

useEffect(() => {
    getTableData()
}, []);

Then I stopped to understand the feature. The second parameter array defines the things that this effect cares about. Basically, the things that it should watch, and if they change, re-run.

So by passing an empty array, you're saying that this effect depends on nothing. So it only runs componentDidMount and comcomponentWillUnmount.

When no 2nd parameter array is passed at all, like where I was at the start, you're telling React that this effect depends on everything. Which is why it was running when tableData was changed, which then called to get more table data.

If tableData wasn't an object but rather a string or float, this probably would have only run 1 time because it doesn't re-run the effect if the dependencies don't change. But with Objects, they're compared by reference instead of deeply comparing the individual values. So even if the getTableData() set the same table data each time, React considers it a new value.

Anyway, I stopped to consider what this effect cares about. I need to fetch data if any of my sort settings change. The final working code is below

const [sort, setSort] = useState({
    dir: 'DESC',
    col: 'service_end_date'
})

useEffect(() => {
    getTableData()
}, [sort]);

Now that I understand how they work, I really like how effects are extremely explicit. You define what you want to happen when a particular thing(s) change. Unlike componentShouldUpdate which is a catch-all for any prop changes.