69

在这个例子中,我有这个反应类:

class MyDiv extends React.component
   constructor(){
      this.state={sampleState:'hello world'}
   }
   render(){
      return <div>{this.state.sampleState}
   }
}

问题是我是否可以为此添加 React 钩子。我知道 React-Hooks 是 React Class 风格的替代品。但是如果我想慢慢迁移到 React hooks 中,我可以在 Classes 中添加有用的 hooks 吗?

4

14 回答 14

135

高阶组件是我们一直在做这类事情的方式,直到钩子出现。您可以为您的钩子编写一个简单的高阶组件包装器。

function withMyHook(Component) {
  return function WrappedComponent(props) {
    const myHookValue = useMyHook();
    return <Component {...props} myHookValue={myHookValue} />;
  }
}

虽然这并不是真正直接使用类组件中的钩子,但这至少允许您使用类组件中的钩子逻辑,而无需重构。

class MyComponent extends React.Component {
  render(){
    const myHookValue = this.props.myHookValue;
    return <div>{myHookValue}</div>;
  }
}

export default withMyHook(MyComponent);
于 2019-01-16T23:43:19.537 回答
23

类组件不支持挂钩 -

根据Hooks-FAQ

你不能在类组件中使用 Hooks,但你绝对可以将类和函数组件与 Hooks 混合在一个树中。组件是使用 Hooks 的类还是函数是该组件的实现细节。从长远来看,我们希望 Hooks 成为人们编写 React 组件的主要方式。

于 2018-11-19T09:14:54.763 回答
5

正如其他答案已经解释的那样,钩子 API 旨在为功能组件提供当前仅在类组件中可用的功能。钩子不应该在类组件中使用。

可以编写类组件以更轻松地迁移到功能组件。

单一状态:

class MyDiv extends Component {
   state = {sampleState: 'hello world'};

   render(){
      const { state } = this;
      const setState = state => this.setState(state);

      return <div onClick={() => setState({sampleState: 1})}>{state.sampleState}</div>;
   }
}

被转换为

const MyDiv = () => {
   const [state, setState] = useState({sampleState: 'hello world'});

   return <div onClick={() => setState({sampleState: 1})}>{state.sampleState}</div>;
}

请注意,useState状态设置器不会自动合并状态属性,这应该用setState(prevState => ({ ...prevState, foo: 1 }));

具有多种状态:

class MyDiv extends Component {
   state = {sampleState: 'hello world'};

   render(){
      const { sampleState } = this.state;
      const setSampleState = sampleState => this.setState({ sampleState });

      return <div onClick={() => setSampleState(1)}>{sampleState}</div>;
   }
}

被转换为

const MyDiv = () => {
   const [sampleState, setSampleState] = useState('hello world');

   return <div onClick={() => setSampleState(1)}>{sampleState}</div>;
}
于 2018-11-19T09:46:52.647 回答
4

钩子不是用于类,而是用于函数。如果您想使用钩子,您可以从编写新代码作为带有钩子的功能组件开始

根据反应常见问题解答

你不能在类组件中使用 Hooks,但你绝对可以将类和函数组件与 Hooks 混合在一个树中。组件是使用 Hooks 的类还是函数是该组件的实现细节。从长远来看,我们希望 Hooks 成为人们编写 React 组件的主要方式。

const MyDiv = () => {
   const [sampleState, setState] = useState('hello world');
   render(){
      return <div>{sampleState}</div>
   }
}
于 2018-11-19T09:15:44.883 回答
4

补充乔尔考克斯的好答案


如果需要更大的灵活性,Render Props还可以在类组件中使用 Hooks:

class MyDiv extends React.Component {
  render() {
    return (
      <HookWrapper
        // pass state/props from inside of MyDiv to Hook
        someProp={42} 
        // process Hook return value
        render={hookValue => <div>Hello World! {hookValue}</div>} 
      />
    );
  }
}

function HookWrapper({ someProp, render }) {
  const hookValue = useCustomHook(someProp);
  return render(hookValue);
}

对于没有返回值的副作用 Hooks:

function HookWrapper({ someProp }) {
  useCustomHook(someProp);
  return null;
}

// ... usage
<HookWrapper someProp={42} />

资料来源:反应训练

于 2020-05-05T22:18:13.713 回答
3

您可以使用react-universal-hooks库。它允许您在类组件的渲染函数中使用“useXXX”函数。

到目前为止,它对我来说效果很好。唯一的问题是,由于它不使用官方钩子,因此值不显示 react-devtools。

为了解决这个问题,我通过包装钩子创建了一个等价物,并让它们将数据存储在component.state.hookValues. (您可以通过自动包装组件render函数来访问组件,以运行 set currentCompBeingRendered = this

有关此问题的更多信息(以及解决方法的详细信息),请参见此处:https ://github.com/salvoravida/react-universal-hooks/issues/7

于 2019-10-25T16:23:56.443 回答
3

React Hooks 让您无需编写类即可使用反应特性和生命周期。它就像类组件的等效版本,具有更小和可读的外形。您应该迁移到 React 钩子,因为编写它很有趣。但是你不能在类组件中编写反应钩子,因为它是为功能组件引入的。

这可以很容易地转换为:

class MyDiv extends React.component
   constructor(){
      this.state={sampleState:'hello world'}
   }
   render(){
      return <div>{this.state.sampleState}
   }
}

const MyDiv = () => {
   const [sampleState, setSampleState] = useState('hello world');
   return <div>{sampleState}</div>
}
于 2019-05-19T13:30:18.333 回答
3

您可以通过通用的高阶组件来实现这一点

HOC

import React from 'react';
const withHook = (Component, useHook, hookName = 'hookvalue') => {
  return function WrappedComponent(props) {
    const hookValue = useHook();
    return <Component {...props} {...{[hookName]: hookValue}} />;
  };
};

export default withHook;

用法

class MyComponent extends React.Component {
      render(){
        const myUseHookValue = this.props.myUseHookValue;
        return <div>{myUseHookValue}</div>;
      }
    }

export default withHook(MyComponent, useHook, 'myUseHookValue');
于 2021-09-01T08:11:25.410 回答
2

有状态组件或容器或基于类的组件曾经支持 React Hooks 的功能,因此我们不需要在有状态组件中仅在无状态组件中使用 React Hooks。

一些附加信息

什么是 React Hooks? 那么什么是钩子呢?Well hooks 是一种新方式,或者为我们提供了一种编写组件的新方式。

到目前为止,我们当然有功能和基于类的组件,对吧?功能组件接收道具,然后您返回一些应该呈现到屏幕上的 JSX 代码。

它们非常适合演示,因此用于呈现 UI 部分,而不是业务逻辑,它们通常专注于每个组件的一个或几个目的。

另一方面,基于类的组件也将接收道具,但它们也具有这种内部状态。因此,基于类的组件是实际持有我们大部分业务逻辑的组件,所以对于业务逻辑,我的意思是我们发出 HTTP 请求,我们需要处理响应并更改应用程序的内部状态,或者可能即使没有 HTTP。用户填写表单,我们想在屏幕上的某个地方显示它,我们需要状态,我们需要基于类的组件,因此我们通常也使用基于类的组件来编排我们的其他组件并传递我们的状态例如,作为功能组件的道具。

现在我们在这种分离中遇到了一个问题,它增加了所有好处,但我们遇到的一个问题是从一种组件形式转换为另一种形式很烦人。这并不难,但很烦人。

如果您发现自己需要将功能组件转换为基于类的组件,则需要大量输入并且总是输入相同的内容,因此很烦人。

引号中一个更大的问题是生命周期钩子很难正确使用。

显然,添加 componentDidMount 并在其中执行一些代码并不难,但是知道要使用哪个生命周期钩子,何时以及如何正确使用它,这可能具有挑战性,尤其是在更复杂的应用程序中,无论如何,如果我们有一种创建组件的方法,然后该超级组件可以处理状态和副作用(如 HTTP 请求)并呈现用户界面?

嗯,这正是钩子的全部意义所在。Hooks 为我们提供了一种创建功能组件的新方法,这很重要。

于 2019-04-04T15:01:42.070 回答
0

您现有的类组件是不可能的。您必须将类组件转换为功能组件,然后执行以下操作 -

function MyDiv() {
const [sampleState, setSampleState] = useState('hello world');
return (
      <div>{sampleState}</div>
    )
}
于 2018-11-19T09:14:59.563 回答
0

对我来说 React.createRef() 很有帮助。

前任。:

constructor(props) {
      super(props);
      this.myRef = React.createRef();
   }

...


<FunctionComponent ref={this.myRef} />

原帖在这里

于 2019-09-16T08:51:40.760 回答
0

我为此做了一个图书馆。反应可挂钩组件

用法很简单。将extends Componentorextends PureComponent替换为extends HookableComponentor extends HookablePureComponent。然后,您可以在render()方法中使用钩子。

import { HookableComponent } from 'react-hookable-component';

//                                  
class ComponentThatUsesHook extends HookableComponent<Props, State> {
    render() {
        //            
        const value = useSomeHook();
        return <span>The value is {value}</span>;
    }
}
于 2022-02-06T07:04:50.437 回答
-1
  1. 尝试使用组件挂钩: https ://github.com/bplok20010/with-component-hooks
import withComponentHooks from 'with-component-hooks';


class MyComponent extends React.Component {

    render(){
        const props = this.props;
        const [counter, set] = React.useState(0);

        //TODO...

    }
}

export default withComponentHooks(MyComponent)

2.尝试react-iifc:https://github.com/EnixCoda/react-iifc

于 2021-02-22T01:53:05.293 回答
-1

的,但不是直接的。

试试 react-iifc,更多细节在它的自述文件中。

https://github.com/EnixCoda/react-iifc

于 2020-07-03T08:17:43.710 回答