为什么高阶组件的语法通常是高阶函数形式的反应?而不是额外的参数?
Why is the syntax for higher order components in react often of the Higher Order Function form? Instead of extra arguments?
我想知道,为什么在 React 中,我们经常看到以下形式的高阶组件:
MyComponent = withSomeHOC(params)(function MyActualCompoent(props) {
return <div/>
})
实现可能如下所示:
function withSomeHOC(params, modifier) {
function(WrappedComponent) {
return function(props) {
//do whatever to modify something based on params.
const data = modifier(React.useContext(someCTX));
return <>
<div>{data}</div>
<WrappedComponent {...props}/>
</>;
}
}
}
而不是更合乎逻辑的方法(对我来说)只是将参数作为第二个(和第三个)参数添加到高阶组件本身:
MyComponent = withSomeHOC(function MyActualComponent(props) {
return <div/>
}, params, modifier);
function(WrappedComponent, params, modifier) {
return function(props) {
//do whatever to modify something based on params.
const data = modifier(React.useContext(someCTX));
return <>
<div>{data}</div>
<WrappedComponent {...props}/>
</>;
}
}
为什么我们几乎看不到第二种方法而几乎总是第一种方法?第二种的缺点是什么?一个优点是更简单的程序结构,而不是深度嵌套的高阶组件和函数。
对于第一种形式,您可以配置一次 HOC 工厂,然后在其他地方使用它。
这实际上是一种装饰器模式。
const preConfigDecorator = withSomeHOC(config)
const DecoratedComp1 = preConfigDecorator(Comp1)
const DecoratedComp2 = preConfigDecorator(Comp2)
如果您的组件是 class 基础,语法会更优雅:
@withSomeHOC(config)
class MyComp extends React.Component {
…
}
我推测这种情况如此普遍的原因之一是使构图更容易。如果您将多个 HoC 应用于单个组件,您可能会得到一些难以阅读的代码,如下所示:
export default withLogging(withRouter(withStuff(Component, arg1a, arg2a), arg1b), arg1c);
Recompose 或类似的库可以让您通过名为 compose
的实用函数将其变成更具可读性的内容。 compose
采用一系列函数并一次调用它们,将一个函数的输出作为输入传递给下一个函数。
但是为了让它工作,所有这些函数都必须是一元的(即,它们必须只接受一个参数)。所以使用您所询问的模式的原因是它可以让您轻松制作一元函数,只需要将一个组件传递给它们。那么这些一元函数就可以组合在一起了。
因此,如果 withLogging
、withRouter
和 withStuff
被重写为遵循您描述的模式,那么它们可以按如下方式使用:
export default compose(
withStuff(arg1a, arg2a),
withRouter(arg1b),
withLogging(arg1c),
)(Component)
我一直在阅读有关柯里化的最新文章和这个:
MyComponent = withSomeHOC(params)(function MyActualCompoent(props) {
return <div/>
})
我觉得很喜欢:
function(a)(a)
从我正在阅读的内容来看,它是为了编写更清晰的代码。正如尼古拉斯所说。
不确定是否有任何性能优势。这是 Whosebug
上的参考
注意:我还是个学习者。
我想知道,为什么在 React 中,我们经常看到以下形式的高阶组件:
MyComponent = withSomeHOC(params)(function MyActualCompoent(props) {
return <div/>
})
实现可能如下所示:
function withSomeHOC(params, modifier) {
function(WrappedComponent) {
return function(props) {
//do whatever to modify something based on params.
const data = modifier(React.useContext(someCTX));
return <>
<div>{data}</div>
<WrappedComponent {...props}/>
</>;
}
}
}
而不是更合乎逻辑的方法(对我来说)只是将参数作为第二个(和第三个)参数添加到高阶组件本身:
MyComponent = withSomeHOC(function MyActualComponent(props) {
return <div/>
}, params, modifier);
function(WrappedComponent, params, modifier) {
return function(props) {
//do whatever to modify something based on params.
const data = modifier(React.useContext(someCTX));
return <>
<div>{data}</div>
<WrappedComponent {...props}/>
</>;
}
}
为什么我们几乎看不到第二种方法而几乎总是第一种方法?第二种的缺点是什么?一个优点是更简单的程序结构,而不是深度嵌套的高阶组件和函数。
对于第一种形式,您可以配置一次 HOC 工厂,然后在其他地方使用它。
这实际上是一种装饰器模式。
const preConfigDecorator = withSomeHOC(config)
const DecoratedComp1 = preConfigDecorator(Comp1)
const DecoratedComp2 = preConfigDecorator(Comp2)
如果您的组件是 class 基础,语法会更优雅:
@withSomeHOC(config)
class MyComp extends React.Component {
…
}
我推测这种情况如此普遍的原因之一是使构图更容易。如果您将多个 HoC 应用于单个组件,您可能会得到一些难以阅读的代码,如下所示:
export default withLogging(withRouter(withStuff(Component, arg1a, arg2a), arg1b), arg1c);
Recompose 或类似的库可以让您通过名为 compose
的实用函数将其变成更具可读性的内容。 compose
采用一系列函数并一次调用它们,将一个函数的输出作为输入传递给下一个函数。
但是为了让它工作,所有这些函数都必须是一元的(即,它们必须只接受一个参数)。所以使用您所询问的模式的原因是它可以让您轻松制作一元函数,只需要将一个组件传递给它们。那么这些一元函数就可以组合在一起了。
因此,如果 withLogging
、withRouter
和 withStuff
被重写为遵循您描述的模式,那么它们可以按如下方式使用:
export default compose(
withStuff(arg1a, arg2a),
withRouter(arg1b),
withLogging(arg1c),
)(Component)
我一直在阅读有关柯里化的最新文章和这个:
MyComponent = withSomeHOC(params)(function MyActualCompoent(props) {
return <div/>
})
我觉得很喜欢:
function(a)(a)
从我正在阅读的内容来看,它是为了编写更清晰的代码。正如尼古拉斯所说。 不确定是否有任何性能优势。这是 Whosebug
上的参考注意:我还是个学习者。