使用 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 世界的趋势是基于函数的组件。在过去一年左右的时间里,情况更是如此,引入了钩子(即 useState
、useEffect
等),它允许您拥有一个轻量级的功能组件,但可以访问赋予基于 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
组件。
有没有人知道为大型组件使用 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 世界的趋势是基于函数的组件。在过去一年左右的时间里,情况更是如此,引入了钩子(即 useState
、useEffect
等),它允许您拥有一个轻量级的功能组件,但可以访问赋予基于 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
组件。