1. ホーム
  2. javascript

[解決済み] React - styled-componentsでpropsを渡す。

2022-03-06 23:11:43

質問

で読んだだけですが styled-components ドキュメント が間違っていて、レンダリング時間に影響を与えるということです。この場合、コードをリファクタリングして、必要なプロップを使用して動的スタイルを作成するにはどうすればよいでしょうか。

よろしくお願いします。

タブコンポーネント

import React from 'react'
import styled from 'styled-components'

const Tab = ({ onClick, isSelected, children }) => {
    const TabWrapper = styled.li`
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 100px;
    margin: 1px;
    font-size: 3em;
    color: ${props => (isSelected ? `white` : `black`)};
    background-color: ${props => (isSelected ? `black` : `#C4C4C4`)};
    cursor: ${props => (isSelected ? 'default' : `pointer`)};
`

    return <TabWrapper onClick={onClick}>{children}</TabWrapper>
}


export default Tab

解決方法は?

ドキュメントが言っているのは、レンダリング コンポーネントの内部にスタイルを含めるのは避けるべきだということだと思います。

これを行う

const StyledWrapper = styled.div`
  /* ... */
`

const Wrapper = ({ message }) => {
  return <StyledWrapper>{message}</StyledWrapper>
}

ではなく、このように

const Wrapper = ({ message }) => {
  // WARNING: THIS IS VERY VERY BAD AND SLOW, DO NOT DO THIS!!!
  const StyledWrapper = styled.div`
    /* ... */
  `

  return <StyledWrapper>{message}</StyledWrapper>
}

なぜなら、コンポーネントの Props が変更されると、コンポーネントが再レンダリングされ、スタイルが再生成されるからです。したがって、それを分離しておくことは理にかなっています。

ということで、さらに先を読むと プロップスに基づく適応 の項では、このように説明されています。

const Button = styled.button`
  /* Adapt the colours based on primary prop */
  background: ${props => props.primary ? "palevioletred" : "white"};
  color: ${props => props.primary ? "white" : "palevioletred"};

  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

// class X extends React.Component {
//  ...

render(
  <div>
    <Button>Normal</Button>
    <Button primary>Primary</Button>
  </div>
);

// }

を使用すると、この機能は動作します。 ボタン コンポーネントはクラス X のプロップを知っており、何も言わなくてもクラス X のプロップを知っています。

あなたのシナリオの場合、解決策は簡単だと想像しています。

const TabWrapper = styled.li`
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 100px;
  margin: 1px;
  font-size: 3em;
  color: ${props => (props.isSelected ? `white` : `black`)};
  background-color: ${props => (props.isSelected ? `black` : `#C4C4C4`)};
  cursor: ${props => (props.isSelected ? 'default' : `pointer`)};
`;

const Tab = ({ onClick, isSelected, children }) => {
  return <TabWrapper onClick={onClick}>{children}</TabWrapper>
}

const X = <Tab onClick={() => console.log('clicked')} isSelected>Some Children</Tab>

私はこれを全くテストしていませんので、自由に試してみて、あなたにとってうまくいったかどうか、あるいは何がうまくいったかを教えてください