Javascript 如何在 React 经典 `class` 组件中使用 React 钩子?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/53371356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I use React hooks in React classic `class` component?
提问by Aminadav Glickshtein
In this example, I have this react class:
在这个例子中,我有这个反应类:
class MyDiv extends React.component
constructor(){
this.state={sampleState:'hello world'}
}
render(){
return <div>{this.state.sampleState}
}
}
The question is if I can add React hooks to this. I understand that React-Hooks is alternative to React Class style. But if I wish to slowly migrate into React hooks, can I add useful hooks into Classes?
问题是我是否可以为此添加 React 钩子。我知道 React-Hooks 是 React Class 风格的替代品。但是如果我想慢慢迁移到 React hooks 中,我可以在 Classes 中添加有用的 hooks 吗?
回答by Joel Cox
High order componentsare how we have been doing this type of thing until hooks came along. You can write a simple high order component wrapper for your hook.
在 hooks 出现之前,高阶组件是我们一直在做这种事情的方式。您可以为钩子编写一个简单的高阶组件包装器。
function withMyHook(Component) {
return function WrappedComponent(props) {
const myHookValue = useMyHook();
return <Component {...props} myHookValue={myHookValue} />;
}
}
While this isn't truly using a hook directly from a class component, this will at least allow you to use the logicof your hook from a class component, without refactoring.
虽然这并不是真正直接从类组件使用钩子,但这至少允许您从类组件使用钩子的逻辑,而无需重构。
class MyDiv extends React.Component {
render(){
const myHookValue = this.props.myHookValue;
return <div>{myHookValue}</div>;
}
}
export default withMyHook(MyDiv);
回答by Gilad Bar
Class components don't support hooks -
类组件不支持钩子 -
According to the Hooks-FAQ:
根据Hooks-FAQ:
You can't use Hooks inside of a class component, but you can definitely mix classes and function components with Hooks in a single tree. Whether a component is a class or a function that uses Hooks is an implementation detail of that component. In the longer term, we expect Hooks to be the primary way people write React components.
您不能在类组件中使用 Hook,但您绝对可以在单个树中将类和函数组件与 Hook 混合使用。组件是使用 Hooks 的类还是函数是该组件的实现细节。从长远来看,我们希望 Hooks 成为人们编写 React 组件的主要方式。
回答by Shubham Khatri
Hooks are not meant to be used for classes but rather functions. If you wish to use hooks, you can start by writing new code as functional components with hooks
钩子不是用于类,而是用于函数。如果你想使用钩子,你可以开始编写新代码作为带有钩子的功能组件
According to React FAQs
You can't use Hooks inside of a class component, but you can definitely mix classes and function components with Hooks in a single tree. Whether a component is a class or a function that uses Hooks is an implementation detail of that component. In the longer term, we expect Hooks to be the primary way people write React components.
您不能在类组件中使用 Hook,但您绝对可以在单个树中将类和函数组件与 Hook 混合使用。组件是使用 Hooks 的类还是函数是该组件的实现细节。从长远来看,我们希望 Hooks 成为人们编写 React 组件的主要方式。
const MyDiv = () => {
const [sampleState, setState] = useState('hello world');
render(){
return <div>{sampleState}</div>
}
}
回答by Estus Flask
As other answers already explain, hooks API was designed to provide function components with functionality that currently is available only in class components. Hooks aren't supposed to used in class components.
正如其他答案已经解释的那样,钩子 API 旨在为函数组件提供当前仅在类组件中可用的功能。钩子不应该在类组件中使用。
Class components can be written to make easier a migration to function components.
可以编写类组件以更轻松地迁移到功能组件。
With a single state:
使用单一状态:
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>;
}
}
is converted to
转换为
const MyDiv = () => {
const [state, setState] = useState({sampleState: 'hello world'});
return <div onClick={() => setState({sampleState: 1})}>{state.sampleState}</div>;
}
Notice that useStatestate setter doesn't merge state properties automatically, this should be covered with setState(prevState => ({ ...prevState, foo: 1 }));
请注意,useState状态设置器不会自动合并状态属性,这应该用setState(prevState => ({ ...prevState, foo: 1 }));
With multiple states:
具有多个状态:
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>;
}
}
is converted to
转换为
const MyDiv = () => {
const [sampleState, setSampleState] = useState('hello world');
return <div onClick={() => setSampleState(1)}>{sampleState}</div>;
}
回答by Allan Duarte
Stateful components or containers or class-based components ever support the functions of React Hooks, so we don't need to React Hooks in Stateful components just in stateless components.
有状态组件或容器或基于类的组件一直支持 React Hooks 的功能,因此我们不需要在有状态组件中只在无状态组件中使用 React Hooks。
Some additional informations
一些附加信息
What are React Hooks?So what are hooks? Well hooks are a new way or offer us a new way of writing our components.
什么是 React Hooks?那么什么是钩子呢?Well hooks 是一种新方法,或者为我们提供了一种编写组件的新方法。
Thus far, of course we have functional and class-based components, right? Functional components receive props and you return some JSX code that should be rendered to the screen.
到目前为止,当然我们有函数式和基于类的组件,对吗?函数式组件接收 props 并返回一些应该呈现到屏幕上的 JSX 代码。
They are great for presentation, so for rendering the UI part, not so much about the business logic and they are typically focused on one or a few purposes per component.
它们非常适合展示,因此对于渲染 UI 部分,与业务逻辑无关,它们通常专注于每个组件的一个或几个目的。
Class-based components on the other hand also will receive props but they also have this internal state. Therefore class-based components are the components which actually hold the majority of our business logic, so with business logic, I mean things like we make an HTTP request and we need to handle the response and to change the internal state of the app or maybe even without HTTP. A user fills out the form and we want to show this somewhere on the screen, we need state for this, we need class-based components for this and therefore we also typically use class based components to orchestrate our other components and pass our state down as props to functional components for example.
另一方面,基于类的组件也将接收道具,但它们也具有这种内部状态。因此,基于类的组件是实际拥有我们大部分业务逻辑的组件,所以对于业务逻辑,我的意思是我们发出 HTTP 请求,我们需要处理响应并更改应用程序的内部状态,或者可能即使没有 HTTP。用户填写表单,我们想在屏幕上的某个地方显示它,我们需要状态,我们需要基于类的组件,因此我们通常也使用基于类的组件来编排我们的其他组件并将我们的状态向下传递例如,作为功能组件的道具。
Now one problem we have with this separation, with all the benefits it adds but one problem we have is that converting from one component form to the other is annoying. It's not really difficult but it is annoying.
现在我们遇到了这种分离的一个问题,它增加了所有的好处,但我们遇到的一个问题是从一种组件形式转换到另一种形式很烦人。这并不难,但很烦人。
If you ever found yourself in a situation where you needed to convert a functional component into a class-based one, it's a lot of typing and a lot of typing of always the same things, so it's annoying.
如果您发现自己需要将功能组件转换为基于类的组件,则需要进行大量输入,而且总是要输入许多相同的内容,因此很烦人。
A bigger problem in quotation marks is that lifecycle hooks can be hard to use right.
引号中的一个更大的问题是生命周期钩子很难正确使用。
Obviously, it's not hard to add componentDidMount and execute some code in there but knowing which lifecycle hook to use, when and how to use it correctly, that can be challenging especially in more complex applications and anyways, wouldn't it be nice if we had one way of creating components and that super component could then handle both state and side effects like HTTP requests and also render the user interface?
显然,添加 componentDidMount 并在其中执行一些代码并不难,但知道使用哪个生命周期钩子,何时以及如何正确使用它,这可能具有挑战性,尤其是在更复杂的应用程序中,无论如何,如果我们有一种创建组件的方法,然后该超级组件可以处理状态和副作用(如 HTTP 请求)并呈现用户界面?
Well, this is exactly what hooks are all about. Hooks give us a new way of creating functional components and that is important.
嗯,这正是钩子的全部意义所在。Hooks 为我们提供了一种创建功能组件的新方法,这很重要。
回答by kk_360
React Hooks let you use react features and lifecycle without writing a class. It's like the equivalent version of the class component with much smaller and readable form factor. You should migrate to React hooks because it's fun to write it. But you can't write react hooks inside a class component, as it's introduced for functional component.
React Hooks 让您无需编写类即可使用 React 功能和生命周期。它就像类组件的等效版本,具有更小且可读的外形。你应该迁移到 React hooks,因为编写它很有趣。但是你不能在类组件中编写 React 钩子,因为它是为功能组件引入的。
This can be easily converted to :
这可以很容易地转换为:
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>
}
回答by Aseem Upadhyay
It won't be possible with your existing class components. You'll have to convert your class component into a functional component and then do something on the lines of -
您现有的类组件将无法实现。您必须将类组件转换为功能组件,然后执行以下操作 -
function MyDiv() {
const [sampleState, setSampleState] = useState('hello world');
return (
<div>{sampleState}</div>
)
}
回答by Venryx
You can use the react-universal-hookslibrary. It lets you use the "useXXX" functions within the render function of class-components.
您可以使用react-universal-hooks库。它允许您在类组件的渲染函数中使用“useXXX”函数。
It's worked great for me so far. The only issue is that since it doesn't use the official hooks, the values don't show react-devtools.
到目前为止,它对我来说效果很好。唯一的问题是,由于它不使用官方挂钩,因此值不显示 react-devtools。
To get around this, I created an equivalent by wrapping the hooks, and having them store their data (using object-mutation to prevent re-renders) on component.state.hookValues. (you can access the component by auto-wrapping the component renderfunctions, to run set currentCompBeingRendered = this)
为了解决这个问题,我通过包装钩子创建了一个等效项,并让它们在component.state.hookValues. (您可以通过自动包装组件render功能来访问组件,以运行 set currentCompBeingRendered = this)
For more info on this issue (and details on the workaround), see here: https://github.com/salvoravida/react-universal-hooks/issues/7
有关此问题的更多信息(以及解决方法的详细信息),请参见此处:https: //github.com/salvoravida/react-universal-hooks/issues/7
回答by ford04
Complementing Joel Cox's good answer
Render Propsalso enable the usage of Hooks inside class components, if more flexibility is needed:
如果需要更大的灵活性,Render Props还可以在类组件中使用 Hook:
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);
}
For side effect Hooks without return value:
对于没有返回值的副作用 Hooks:
function HookWrapper({ someProp }) {
useCustomHook(someProp);
return null;
}
// ... usage
<HookWrapper someProp={42} />
Source: React Training
资料来源:反应培训

