React笔记 绕开hook对class的限制

发生背景

又是React Router DOM v6的坑。
有个路由是/news/:number,路径参数要通过useParamshook获取,而hook不支持在类组件中使用。
location.href也得用useLocationhook获取,否则提示未声明。

相关代码

/src/pages/news/index.tsx(缩减版):

class NewsDetail extends React.Component {
  state: NewsDetailState = {
    news: {
      id: "",
      number: "", // number字段是string类型的
      title: "name",
      content: "",
      element: <Spin />
    }
  }
  constructor(props: NewsDetailProps) {
    super(props);
    let state = this.state;
    state.news.number = useParams().id as string;
    state.news.element = (<>
      <Grid.Row justify='center'>
        <Typography.Title heading={ 1 }>{ state.news.title }</Typography.Title>
      </Grid.Row>
      ...
    </>);
    this.setState(state);
  }
  render(): React.ReactNode {
    return (<div><article>
      { this.state.news.element }
    </article></div>);
  }
}
export default NewsDetail;

错误信息

Compiled with problems:

ERROR

[eslint] 
src\pages\news\detail.tsx
  Line 14:25:  React Hook "useParams" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function  react-hooks/rules-of-hooks

解决方案

做一个withRouter通用函数,伪装成组件,取到hook后传给实际组件。
diff(/src/pages/news/index.tsx):

@@ -11,7 +11,7 @@ class NewsDetail extends React.Component {
   constructor(props: NewsDetailProps) {
     super(props);
     let state = this.state;
-    state.news.number = useParams().id as string;
+    state.news.number = props._params.id;
     state.news.element = (<>
       <Grid.Row justify='center'>
         <Typography.Title heading={ 1 }>{ state.news.title }</Typography.Title>

diff(/src/util/with_router.tsx):

@@ -0,0 +1,8 @@
+import { useParams } from "react-router-dom";
+function withRouter(Child) {
+  return (props) => {
+    let params = useParams();
+    return <Child { ...props } _params={ params } />;
+  }
+}
+export { withRouter };

发生原因

React官方强推函数组件,没有像Vue那样的平滑过渡。
本人习惯用类组件,看不惯函数组件,于是搞了这个……
(点名批评React)(狂赞Vue)

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值