使用useState-hook从内部更改样式化的组件

时间:2019-05-25 08:16:34

标签: reactjs styled-components

我正在制作要在我的项目中使用的组件库-之前我已经使用过样式化组件很多,这是将样式应用于组件的首选方式。我最喜欢的是能够使我的组件完全发挥功能并且自成一体的功能。

我有一个问题,但我确实无法解决令人满意的问题。

我想做这样的事情,但是无论如何,我似乎都无法从样式组件中访问或设置道具。

import React, { useState } from 'react';
import styled from 'styled-components';

const Button = ({ className }) => {
  const [clicked, setClicked] = useState(false);
  return (
    <button className={className} clicked={clicked} onClick={() => setClicked(!clicked)}>
      {this.props.children}
    </button>
  );
};

export default styled(Button)`
  ${applySomeStyle}
  ${props => props.clicked} {
    ${applySomeOtherStyle}
  }
`;

我已经能够通过这样做来“解决”它,但是仅仅为了这个目的创建一个虚拟组件似乎是多余的。能够执行示例1中的操作似乎更为自然。

import React, { useState } from 'react';
import styled from 'styled-components';

const Dummy = styled.button``;

const Button = ({ className }) => {
  const [clicked, setClicked] = useState(false);
  return (
    <Dummy className={className} clicked={clicked} onClick={() => setClicked(!clicked)}>
      {this.props.children}
    </Dummy>
  );
};

export default styled(Button)`
  ${applySomeStyle}
  ${Dummy} {
     ${props => props.clicked} {
       ${applySomeOtherStyle}
     }
  }
`;

编辑:建议的链接问题不适用。第一个与之相关的问题是,一个人本质上是在问如何将道具传递给他的孩子。第二个问题是相似的,但是答案已经过时,因为它早于useState挂钩,它使我们不能使用Class组件(该问题的答案基本上是说样式组件不能在Class组件中使用)。

2 个答案:

答案 0 :(得分:0)

styled()无法引用内部状态。无论是类和this.state还是函数和useState钩子都没有关系。处理组件的唯一方法是将组件分为两种:一种是处理状态更改,另一种是根据道具封装更改。

import React, { useState } from 'react';
import styled from 'styled-components';

const InnerButton = styled(button)`
  ${props => props.clicked} {
    ${applySomeOtherStyle}
  }
`;

const Button = ({ className }) => {
  const [clicked, setClicked] = useState(false);
  return (
    <InnerButton className={className} clicked={clicked} onClick={() => setClicked(!clicked)}>
      {this.props.children}
    </InnerButton>
  );
};

export default styled(Button)`
  ${applySomeStyle}
`;

答案 1 :(得分:0)

您是否尝试过使用挂钩有条件地设置className?像这样...

import React, { useState } from 'react';
import styled from 'styled-components';

const ButtonStyled = styled('button')`
  .className {
    color: red;
}
`
export const Button = () => {
  const [clicked, setClicked] = useState(false);
  return (
    <ButtonStyled className={clicked ? 'className' : ''} clicked={clicked} onClick={() => setClicked(!clicked)}>
      {this.props.children}
    </ButtonStyled>
)}

或者,如果您从样式组件中导入css属性,则可以执行以下操作...。

import React, { useState } from 'react';
import styled, { css } from 'styled-components'

const ButtonStyled = styled('button')`
  ${({ clicked }) =>
    clicked &&
    css`
      color: red;
    }
`
export const Button = () => {
  const [clicked, setClicked] = useState(false);
  return (
    <ButtonStyled clicked={clicked} onClick={() => setClicked(!clicked)}>
      {this.props.children}
    </ButtonStyled>
)}