【问题标题】:Conditional styling using Styled Components使用样式化组件的条件样式
【发布时间】:2021-07-02 17:52:12
【问题描述】:

我已经尝试了几个小时来解决这个问题,我相信答案很简单。当一个项目被点击时,它最终会为我的待办事项列表创建一个过滤器。我正在努力做的是应用条件样式,以便“活动”项目的字体颜色为蓝色。

我已将status 作为道具包含在内,但我似乎无法在样式组件中使用它以及道具。

来自我的 App.js:

import { useState } from 'react'

function App() {
  const [ status, setStatus ] = useState("all")

  return (
    <Filter status={status} setStatus={setStatus}/>
  )
}

过滤器.js

const Container = styled.div`
    display: flex;
    justify-content: center;
`

const Item = styled.p`
   color: red;

   // I'm trying to do something like this..

   ${(status, props) => {
        if (status === props.id) {
            return `
                color: blue;
            `
        }
    }}
   
`

export const Filter = ({ setStatus, status }) => {
    
    const statusHandler = (e) => {
        if (e.target.id) {
            setStatus(e.target.id)        
        }
    }
    
    return (
        <div>
          <Container onClick={statusHandler}>
            <Item id="all">All</Item>
            <Item id="active">Active</Item>
            <Item id="completed">Completed</Item>
          </Container>
        </div>
    )
}

【问题讨论】:

  • props.id 来自哪里?我看到状态为 status={status},但没有看到 ID。

标签: reactjs styled-components


【解决方案1】:

statusid 两个props 传递给Item 组件,并在props 回调中进行比较。

const Item = styled.p`
  color: red;

  ${({ id, status }) => status === id && 'color: blue; '}
`;

用法:

<Item id="all" status={status}>All</Item>

演示

可以使用单个道具使这更简单,并在组件中进行条件测试。

const Item = styled.p`
  color: red;

  ${({ isStatusMatch }) => isStatusMatch && "color: blue;"}
`;

...

<Item isStatusMatch={status === 'all'}>All</Item>

完整的演示代码:

const Item = styled.p`
  color: red;
  ${({ id, status }) => status === id && "color: blue;"}
`;

const Item2 = styled.p.attrs(({ id, status }) => ({
  className: id === status && "statusMatch"
}))`
  color: red;
  &.statusMatch {
    color: blue;
  }
`;

const Item3 = styled.p`
  color: red;
  ${({ statusMatch }) => statusMatch && "color: blue;"}
`;

function App() {
  return (
    <div className="App">
      <Item id="test" status="test">
        test
      </Item>
      <Item id="nottest" status="test">
        not test
      </Item>

      <Item2 id="test" status="test">
        test
      </Item2>
      <Item2 id="nottest" status="test">
        not test
      </Item2>

      <Item3 statusMatch={"test" === "test"}>test</Item3>
      <Item3 statusMatch={"nottest" === "test"}>not test</Item3>
    </div>
  );
}

【讨论】:

    【解决方案2】:

    我认为执行此任务的最简单方法是在要更改颜色的元素处添加一个类。

    所以你的项目将是

    const Item = styled.p`
       color: black;
       &.selected {
        color: red
       }
    

    你的组件将是:

    <>
        <Item id="all" className={status === "all" ? "selected" : null}>All</Item>
        <Item id="active" className={status === "active" ? "selected" : null}>Active</Item>
        <Item id="completed" className={status === "completed" ? "selected" : null}>Completed</Item>
    </>
    

    为避免编写重复代码,您可以循环这些值。我们开始吧:

    const items = [
        {
            id: "all",
            value: "All"
        },
        {
            id: "active",
            value: "Active"
        },
        {
            id: "completed",
            value: "Completed"
        },
    ]
    
    items.map(({id, value}) => (
        <Item key={id} id={id} className={status === id ? "selected" : null}>{value}</Item>
    ))
    

    如果可以保留在 React 中,则无需将逻辑放入样式化组件中

    【讨论】:

      【解决方案3】:

      你可以试试这样的:

      // YOUR STYLES
      const activeStyles = (props) => ({
        color: props.status === props.id ? 'blue' : null
      });
      
      // YOUR FILTER COMPONENT
          return (
              <div>
                <Container onClick={statusHandler}>
                  <Item id="all" styles={{...activeStyles({status, id:'all'})}}>All</Item>
                  <Item id="active" styles={{...activeStyles({status, id:'active'})}}>Active</Item>
                  <Item id="completed" styles={{...activeStyles({status, id:'completed'})}}>Completed</Item>
                </Container>
              </div>
          )
      
      

      【讨论】:

        猜你喜欢
        • 2020-09-26
        • 2020-09-22
        • 2018-10-16
        • 2021-12-13
        • 1970-01-01
        • 2020-10-27
        • 1970-01-01
        • 2021-01-12
        • 2021-09-06
        相关资源
        最近更新 更多