やったこと
ハッカソンの準備
useContextでのエラー
  <ApplyUseLanguageContext.Provider value={applyUseLanguage} >
  </ApplyUseLanguageContext.Provider>
上のように単体でContextに値を入れた場合、ずっとオブジェクトとして渡されると思っていた
そのため、下のように
	const { applyStartDate } = useContext(ApplyStartDateContext)
オブジェクトとして受け取っていたらずっと ~~ does not exists type ~~のエラーが出ていた
正しい回答としては、
	const applyStartDate = useContext(ApplyStartDateContext)
である。
constateについて
contextを分離させるために、頑張った結果が以下の写真だ

実装としては正解らしい。。。が、みてられないくらい量が多い  
これを解決してくれるのがconstateである。
github source code
使用方法
$ npm install constate --save
# or
$ yarn add constate
まずはinstallから
設置
import { useState } from 'react';
import constate from 'constate';
const [CountProvider, useCountContext] = constate(() => {
  const [count] = useState(0);
  return count;
});
constateを使った結果
export const [RecruteTitleProvider, useRecruteTitleContext, useSetRecruteTitleContext] = constate(() => {
  const [recruteTitle, setRecruteTitle] =
    useState<string | undefined>(undefined);
  return { recruteTitle, setRecruteTitle };
},
  value => value.recruteTitle,
  value => value.setRecruteTitle
);
export const [RecruteUseLanguageProvider, useRecruteUseLanguageContext, useSetRecruteUseLanguageContext] =
  constate(() => {
    const [recruteUseLanguage, setRecruteUseLanguage] =
      useState<string | undefined>(undefined);
    return { recruteUseLanguage, setRecruteUseLanguage };
  },
    value => value.recruteUseLanguage,
    value => value.setRecruteUseLanguage
  );
export const [RecruteDateProvider, useRecruteStartDateContext, useSetStartRecruteDateContext, useEndRecruteDateContext, useSetEndRecruteDateContext] = constate(() => {
	const [recruteStartDate, setRecruteStartDate] = useState<Date | null | undefined>(null)
	const [recruteEndDate, setRecruteEndDate] = useState<Date | null | undefined>(null)
	return { recruteStartDate, setRecruteStartDate, recruteEndDate, setRecruteEndDate }
},
  value => value.recruteStartDate,
  value => value.setRecruteStartDate,
  value => value.recruteEndDate,
  value => value.setRecruteEndDate,
)
export const RecrutePostProvider = (props: { children: ReactNode }) => {
  const { children } = props;
  return (
    <RecruteTitleProvider>
      <RecruteUseLanguageProvider>
	<RecruteDateProvider>
	  {children}
	</RecruteDateProvider>
      </RecruteUseLanguageProvider>
    </RecruteTitleProvider>
  );
};
こうなる
しかし、実際にContextを使うと依存関係が増えるためなるべく使わない設計にするべき
簡潔なまとめ
上のだとちょっとみずらいので簡潔なパターンを掲示
export const [countProvider, useCountContext, useSetCountContext] = constate(() => {
  const [count, setCount] =
    useState<number>(0);
  return { count, setCount };
  },
  value => value.count,
  value => value.setCount
);
- constateの第二引数以降に、第一引数の関数の返り値をセレクターで分割することで、内部でContext分割してくれる
 - この場合だとcountProviderは2つのProviderを内包するReactNodeになる
 - 残りの二つのHookはそれぞれのConsumerになる
 
ReactNodeとは
type ReactNode =
  | ReactChild
  | ReactFragment
  | ReactPortal
  | boolean
  | null
  | undefined
という定義になっている
ReactNodeが使われるのは、createElementの引数
function createElement<P extends HTMLAttributes<T>, T extends HTMLElement>(
  type: keyof ReactHTML,
  props?: (ClassAttributes<T> & P) | null,
  ...children: ReactNode[]
): DetailedReactHTMLElement<P, T>
ReactChild
ReactNodeに含まれるReactChildは
type ReactChild = ReactElement | ReactText
- props.childrenには直接関係はない
 - ReactChild は ReactNode の型定義で使われているだけ
    
ReactText
type ReactText = string | number - primitive なものを 2 つ組み合わせただけのもの
これによって、以下のようにコンポーネントのchildrenにprimitiveなものも含むことができるようになる
    
const Hoge = () => { return <div>1</div> } 
参考資料