Javascript 反应-如何确定组件是否为无状态/功能性组件?
我有功能性/无状态组件和从Javascript 反应-如何确定组件是否为无状态/功能性组件?,javascript,reactjs,Javascript,Reactjs,我有功能性/无状态组件和从React.component继承的组件: const Component1 = () => (<span>Hello</span>) class Component2 extends React.Component { render() { return (<span>Hello</span>) } } 您可以检查它的原型,例如: function isStateless(Component)
React.component
继承的组件:
const Component1 = () => (<span>Hello</span>)
class Component2 extends React.Component {
render() {
return (<span>Hello</span>)
}
}
您可以检查它的原型,例如:
function isStateless(Component) {
return !Component.prototype.render;
}
这取决于人们所谓的“无状态”。 如果无状态的意思是“不能有
ref
”,那么它是:
function isStateless(Component) {
return typeof Component !== 'string' && !Component.prototype.render
}
更新:还有一个新的
PropTypes.elementType
类型用于React组件(不是“元素”)。类组件本质上是有状态的,但是随着React钩子的引入,功能组件不再称为无状态的,因为它们也可以是有状态的
isReactComponent
自React 0.14以来,React.Component
上存在特殊属性。这允许确定组件是否为类组件
function isFunctionalComponent(Component) {
return (
typeof Component === 'function' // can be various things
&& !(
Component.prototype // native arrows don't have prototypes
&& Component.prototype.isReactComponent // special property
)
);
}
function isClassComponent(Component) {
return !!(
typeof Component === 'function'
&& Component.prototype
&& Component.prototype.isReactComponent
);
}
在React代码库中执行类似的检查
由于组件可以是上下文提供者
或消费者
,因此isFunctionalComponent(Component)
可能不等于!isClassComponent(Component)
现在我可以(React 16.12.0)测试组件是否是函数了。
(我需要它来处理是否需要使用React.forwardRef
包装组件以避免以下问题)
为什么你需要知道这一点?@JuanMendes我可以使用
React.createElement
函数设置ref
prop,但功能组件不能有ref。当时我不知道组件类型(它是动态的)。你想在组件本身之外设置refs吗?你的问题就像“如何知道函数中是否有bug?”@JuanMendes你尝试时会得到警告:createElement(()=>null,{ref:'myRef'})
更正函数,它有bug。查看下面我的答案。请检查它的字符串是否正确。如果render
是实例方法,render=()=>…
组件可能没有原型
谁对这个答案投了反对票,这将不起作用?这是正确的。因为字符串有时可以使用react.Yes进行呈现,可以将ref
分配给字符串组件(如“div”)并使其有效,而无状态组件不能具有ref
s,因为它们没有自己的DOM节点。我想这取决于如何定义“无状态”。不要忘记片段和返回数组作为子元素。实际上,组件
不是元素
,因此组件既不能是数组也不能是片段。
function isFunctionalComponent(Component) {
return (
typeof Component === 'function' // can be various things
&& !(
Component.prototype // native arrows don't have prototypes
&& Component.prototype.isReactComponent // special property
)
);
}
function isClassComponent(Component) {
return !!(
typeof Component === 'function'
&& Component.prototype
&& Component.prototype.isReactComponent
);
}
(typeof component === "object" && typeof component.type === "function")