Debug values using getters or Proxy

Toru Kobayashi
2 min readDec 7, 2021

Getters and Proxy are useful features in JavaScript when you want to track accessing the values. For example, you can only rerender components that used changed values by tracking the usage of values with getters and Proxy.

SWR adopts the approach to optimize rendering and you can see it in the following document.

The following is the implementation.

return {
mutate: boundMutate,
get data() {
stateDependencies.data = true
return data
},
get error() {
stateDependencies.error = true
return error
},
get isValidating() {
stateDependencies.isValidating = true
return isValidating
}
} as SWRResponse<Data, Error>

The returned object is what useSWR returns and stateDependencies is an object to track the usage. The properties of the returned object are implemented as getter functions, so it’s marked as “used” when we access these properties.

// the data is marked as "used"
const { data } = useSWR("/api/foo");

This is cool!

But you should be careful when debugging. If you add console.log to debug the values, you might encounter an unexpected behavior.

const { data, error, isValidating } = useSWR("/api/foo");
console.log({ data, error, isValidating });
// Now it renders everytime these values are changed not only data.

In the above case, this increases rendering count because this marked all values as “used”.

SWR uses getter functions, but it can be applied to libraries that use Proxy for the same purpose. So we should be careful about debugging when we deal with libraries that use getter functions or Proxy for optimization.

I’ve encountered this when I worked on swr-devtools. Currently, this devtool inspects the cache data by defining a getter function to the cache store. But SWR introduced the middleware feature at v1.0.0 so I wanted to try using the middleware to inspect the cache data. But it caused this problem and I had to reconsider the approach.

I’ve also tried to add useDebugValue, which is a built-in hook of React, because it is useful for debugging.

But this also caused the same problem and I’ve suspended it.

I know developing devtools is not common, but “console debug” is a common way to find a problem. If you encountered a problem like “This only happens on debugging”, I recommend you suspect getter functions or Proxy.

--

--