Я думаю, что @TvG сказал прямо на месте. Сравнение объектов осуществляется по ссылкам.
Когда вы создаете объект так, как вы это делали в коде, каждый раз будет создаваться новый ссылочный объект.
const role = useRole({ data: {} });
Даже если вы делаете это так:
let defaultRole = { data: {} }
const role = useRole(defaultRole);
Он будет каждый раз создавать новый объект. значение defaultRole будет пересчитываться при каждом рендере.
Что можно сделать здесь, так это то, что React предоставляет нам метод useRef, который не будет изменяться при повторном отображении, если он не был изменен явно. Вот ссылка для чтения:
useRef docs
Вы можете сделать что-то вроде этого:
Сверните вопрос, почему в этом случае будет работать объект типа data = {}.
Так что ваше useRole имеет эффект, который зависит от данных. Допустим, вы назвали useRole как useRole ({})
теперь в вашем useRole вы распространяете значение данных из этого переданного объекта {}
так что эта строка
export function useRole({ data }) {
// data will be evaluated as undefined and undefined will remain same on //consecutive rerenders and hence the effect will not run
}
Это причина, по которой он работает, когда вы передаете пустой объект useRole.
Надеюсь, это поможет.
Для понимания попробуйте распечатать значение данных в useRole, вы обязательно поймете это:)
1 === 1 //true
undefined === undefined //true
{} === {} // false