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

Aas*_*sen 4 reactjs styled-components react-hooks

我正在制作一个组件库以在我的项目中使用 - 我之前已经使用过很多样式组件,这是我将样式应用于组件的首选方式。我最喜欢它的是能够使我的组件功能齐全且独立。

我有一个问题,但我还没有真正能够令人满意地解决。

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

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}
  }
`;
Run Code Online (Sandbox Code Playgroud)

我已经能够通过这样做来“解决”它,但是仅仅为了这个目的创建一个虚拟组件似乎是非常多余的。能够做我在示例 #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}
     }
  }
`;
Run Code Online (Sandbox Code Playgroud)

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

sky*_*yer 5

styled()不能指内在状态。它是类和this.state/或函数和useState钩子并不重要。处理这个问题的唯一方法是将组件分成两部分:第一个处理状态更改,另一个根据 props 封装更改。

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}
`;
Run Code Online (Sandbox Code Playgroud)