Провайдер контекст транслирует дочерним компонентам какое-то значение.
Это может быть состояние (реактивное и изменяемое), могут быть какие-то функции (например, для изменения состояния), может быть вообще просто нативный объект (например, какая-то конфигурация приложения, которую не нужно менять) или просто константа (ну, вдруг пнадобится). Тут все зависит от того, что требуется передать вниз по дереву компонентов.
Соответственно, если нужно что-то изменяющееся, отслеживаемое и реактивное, то да, надо передавать состояние (state провайдера) и без него никак.
Это очень похоже на Redux. Но не стоит беспокоиться, что на каждый чих провайдер будет перерисовывать все дерево. Просто детей надо передавать в провайдер через children. В таком случае при изменении стейта будут ререндериться только Consumer-ы этого контекста (или те компоненты, которые используют useContext).