タイトルの通りです。あるコンポーネント内で配下にある全ての子要素(styled-componentsでラップされたものであるとします)に共通したpropsを渡す場合のやり方の話です。愚直に書いていたらキリがなく最悪なコードが出来上がります。
結論
styled-components/ThemeContext
を使おう。
import { ThemeContext } from 'styled-components'
具体例
まずこんな感じの複雑なコンポーネント Component
が存在しているとします。多くのコンポーネントやDOMを内包していますが、それらは全てstyled-componentsでラップされています。
const A = styled.div`
/* ... */
${props => props.value}
/* ... */
`
const B = styled.div`
/* ... */
${props => props.value}
/* ... */
`
const C = styled.div`
/* ... */
${props => props.value}
/* ... */
`
// ...
const Z = styled.div`
/* ... */
${props => props.value}
/* ... */
`
const Component = () => {
return (
<Container>
<A />
<B />
<C />
{/* ... */}
<Z />
</Container>
)
}
ここで、全ての(あるいは殆どの)内包したコンポーネントで value
という共通した値を使いまわしたいとします。(この value
は useContext
などで更に上層から受け取ったものとします)
そんな時に、こんなこと↓なんてやていられません。
const Component = () => {
return (
<Container>
<A value={value} />
<B value={value} />
<C value={value} />
{/* ... */}
<Z value={value} />
</Container>
)
}
こういうときは ThemeContext
を使いましょう、一発で解決します。
const Component = () => {
return (
<ThemeContext.Provider value={/* 任意の値 */}>
<Container>
<A />
<B />
<C />
{/* ... */}
<Z />
</Container>
</ThemeContext.Provider>
)
}
ただし、注意点として呼び出す際のpropsのプロパティがtheme
になるので、既に違うプロパティで定義してる場合は修正しましょう。
- ${props => props.value}
+ ${props => props.theme}
また当然ではありますがtheme
にオブジェクトを渡すことでpropsを一層ラップした状態でこれまで通りに値を扱えます。
interface Attrs {
// 渡したいpropsの型定義
}
const A = styled.div`
/* ... */
${({ theme: props }: { theme: Attrs }) => props.aaa}
${({ theme: props }: { theme: Attrs }) => props.bbb}
${({ theme: props }: { theme: Attrs }) => props.ccc}
/* ... */
`
const Component = () => {
const attrs: Attrs = { /* ... */ }
return (
<ThemeContext.Provider value={attrs}>
<Container>
<A />
<B />
<C />
...
<Z />
</Container>
</ThemeContext.Provider>
)
}
以上です。
Top comments (0)