gpt4 book ai didi

javascript - 将 HOC 重构为钩子(Hook)

转载 作者:行者123 更新时间:2023-11-29 22:55:09 25 4
gpt4 key购买 nike

在我花在 React 和几篇文章上的时间里,我问自己如何将 HOC 重构为钩子(Hook),以及它是否有用以及为什么,

这是一个需要重构的小组件

function withSpacing(Component) {
const WrappedWithSpacing = ({
pv, ph, pt, pb, pl, pr, style, ...props
}) => {

const styleWithSpacing = {};

const spacing = layout.padding;

const paddingTop = pt || pv;
const paddingBottom = pb || pv;
const paddingRight = pr || ph;
const paddingLeft = pl || ph;

if(paddingTop > 0) styleWithSpacing.paddingTop = paddingTop * spacing;
if(paddingBottom > 0) styleWithSpacing.paddingBottom = paddingBottom * spacing;
if(paddingLeft > 0) styleWithSpacing.paddingLeft = paddingLeft * spacing;
if(paddingRight > 0) styleWithSpacing.paddingRight = paddingRight * spacing;

return <Component style={{...style, ...styleWithSpacing}} {...props} />
}

WrappedWithSpacing.propTypes = {
pv: PropTypes.number,
ph: PropTypes.number,
pt: PropTypes.number,
pb: PropTypes.number,
pl: PropTypes.number,
pr: PropTypes.number,
style: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
}

WrappedWithSpacing.defaultProps = {
pv: 0,
ph: 0,
pt: 0,
pb: 0,
pr: 0,
pl: 0,
}

return WrappedWithSpacing;
}

export default withSpacing;

根据官方文档:

Do Hooks replace render props and higher-order components?

Often, render props and higher-order components render only a single child. We think Hooks are a simpler way to serve this use case. There is still a place for both patterns (for example, a virtual scroller component might have a renderItem prop, or a visual container component might have its own DOM structure). But in most cases, Hooks will be sufficient and can help reduce nesting in your tree.

我使用这个 HOC 只是为了给组件添加一些预定义的空间。

将其重构为钩子(Hook)真的会更好,你能解释一下为什么吗?

如果是,将其重构为 hook 的最佳方法是什么?

最佳答案

TDLR;因为您的 HOC 没有任何状态或订阅,所以没有正当理由使用 Hook 重构您的组件。

React Hooks 引入了几个新功能来响应以补充其基于类的对应项。 useState 补充 this.state ( docs ) 作为一种在渲染之间存储状态的功能性方式。 useEffect 补充了 componentDidMountcomponenetDidUnmount 方法 ( docs ),它提供了一种方法来执行功能性 React 组件的设置和拆卸。

如果您从文档中获取了像这样的 HOC:

// This function takes a component...
function withSubscription(WrappedComponent, selectData) {
// ...and returns another component...
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: selectData(DataSource, props)
};
}

componentDidMount() {
// ... that takes care of the subscription...
DataSource.addChangeListener(this.handleChange);
}

componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}

handleChange() {
this.setState({
data: selectData(DataSource, this.props)
});
}

render() {
// ... and renders the wrapped component with the fresh data!
// Notice that we pass through any additional props
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}

并将其转换为功能组件,您可能会得到这样的结果:

function withSubscription(WrappedComponent, selectData) {
return function WrappedComponent (props) {
const [myData, setMyData] = useState(null);

useEffect(() => {
const handleMyDataChange = newData => {
setMyData(newData);
}

DataSource.addChangeListener(handleMyDataChange);

return function cleanup() {
DataSource.removeChangeListener(handleMyDataChange);
};
});

return <WrappedComponent data={data} {...this.props} />;
}

您的填充和间距会在每次渲染时重新生成。由于您问题中的代码在渲染之间没有任何持续存在的内容,因此尝试将其重构为实现 React Hooks 的组件没有多大意义。 React Hooks 更适合将基于类的 React 组件转换为函数式 React 组件。

关于javascript - 将 HOC 重构为钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56776095/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com