使用 React 无状态组件很奇怪

Strange using React stateless components

有没有人知道为大型组件使用 React 无状态组件的原因,方法定义为变量等。我最近加入了一个项目,其中使用了这样的方法。我很困惑。

我想还是用小组件比较好,但还是

也许有一些合乎逻辑的解释,比如性能等

简单代码示例:

const myComponent = ({p1, p2, p3}) => {
    const buttonProps = {
        className: 'button',
        onClick: () => { console.log('clicked'); }
    };
    const getButtonName = () => 'Submit'; 
    const getButton = () => {
        return (
            <button ...buttonProps>{getButtonName()}<button>
        );
    }
    /* a lot of defined objects like above */
    return (
        <div>
            {getButton()}
        </div>
    );
}

主要问题是为什么使用像 getButton() 这样的方法而不是创建 MyButton 组件。我想它会很容易理解,调试等

扩展 React.Component 的有状态组件有很多额外功能。您基本上是在导入 React.Component 内置的所有变量和函数,例如生命周期函数。如果您不需要它们,那么 stateless 只会创建一个更轻的组件。例如,当您的组件挂载时,有状态组件将调用 componentDidMount() 而无状态组件甚至没有 componentDidMount()。

编辑:回答您更具体的问题: 这种函数是一个组件,一个功能组件,可以重用,但在功能组件的渲染函数中,不能使用 <> 语法调用该组件。它位于另一个组件内,因此它的范围仅限于父组件,因此它可以访问道具。它有点基于意见,因为使用一种组件而不是另一种组件只是可读性、可重用性和功能性的平衡。

在 React 中,您可以拥有基于 class 的组件,或基于函数的组件(功能组件)。

函数式组件通常更容易测试和理解,也更轻量。

React 世界的趋势是基于函数的组件。在过去一年左右的时间里,情况更是如此,引入了钩子(即 useStateuseEffect 等),它允许您拥有一个轻量级的功能组件,但可以访问赋予基于 class 的组件额外的能力。

基于 class 的组件本身没有什么问题,但趋势与它们背道而驰,所以听到你说你加入了一个不使用它们的项目我并不感到惊讶。

您可能对 2018 年的 React Conf 视频之一感兴趣,其中介绍了 hooks:React Conf 2018 相关部分大约从 11:30 开始。

A stateless component 表示它没有 state,您示例中的 React 组件将被视为 functional component。至于模式本身,它也可以在 class component 中实现——它不是特定于 functional components.

的东西

例如,上面的代码可以像下面这样写,并且会产生完全相同的结果:

class MyComponent extends React.Component {
  render() {
    const buttonProps = {
      className: `button`,
      onClick: () => {}
    }
    const getButtonName = () => `Submit`
    const getButton = () => {
      return (
        <button {...buttonProps}>{getButtonName()}</button>
      )
    }
    return (
      <div>{getButton()}</div>
    )
  }
}

我不了解上下文,所以很难弄清楚为什么要这样做 - 最好询问负责选择以这种方式编写组件的开发人员以找出原因。

不幸的是,或者幸运的是,React 没有固执己见,人们可以随心所欲地做自己想做的事,这可能会导致 "strange" 模式 不是 总是好的。

您提供的代码片段创建了不必要的抽象,乍一看并不清晰 - 我必须弄清楚 getButton 的作用,然后转到 getButtonName 查看内部呈现的内容button 元素,然后我不得不搜索 buttonProps 以找出正在传递的 props

如果您真的需要一个 returns 组件的可重用功能,那么为什么不直接使用“React”方式呢?

function Button({ children, ...rest }) {
  const defaultProps = {
    className: `button`,
    onClick: () => {}
  }
  const props = { ...defaultProps, ...rest }

  return (
    <button {...props}>
      {children}
    </button>
  )
}

然后,回到你的例子,可以在下面的例子中使用:

// by the way, start with an uppercase when naming React components
const MyComponent = ({ p1, p2, p3 }) => {
  return (
    <div>
      <Button>I am a button #1!</Button>
      <Button
        onClick={() => console.log(`HelloWorld`)}
      >
        I am a button #2 with a custom `onClick` handler!
      </Button>
    </div>
  )
}

这种方法更好更简洁,所以正如您在评论中建议的那样,getButton 应该写成一个实际的 React 组件。