DailyENJS is dedicated to translating excellent front-end English technical articles to bring better technical vision to technical students.

introduce

When I first heard about Hooks, I was so excited. As I read the documentation, Hooks seem magical – function parts as rich as class parts? Hooks make things like life cycles or state; Or the complex syntax and low reusability of some of the internal logic in the class were solved.

Hooks eliminate the need for complex patterns such as render-props or HOC. This not only makes the code cleaner, but also reduces the likelihood of errors.

The reusability of complex logic is also greatly improved, as we now have the option to package things like state and “lifecycle methods” directly into a function. This creates a lot of room for imagination that could not have been done before Hooks. Functions become more powerful, and they can be reused not only across the entire project, but across many different projects. Because the logic they implement is completely generic.

I’m most excited about combining various Hook functions into more powerful ones. These functions can also be combined again into more powerful functions. Believe me, after you start using Hooks, you can’t live without them.

The problem

If everything is beautiful and magical, what’s wrong with it? I don’t see any problems when the community adopts Hooks.

But the reality is that you want to use class-based Hook logic in your project, and there is currently no way to rewrite these class components as Hooks. The class might be too complex, or if you change it, you might break many other things in the project. The commercial value of this approach is also questionable. If you go to the React document, you’ll see an interesting statement:

But, as with everything in the JavaScript world, there is a solution. You can effectively use Hooks logic within classes without violating any React rules.

The solution

I use a simple useScreenWidth Hook as an example. As you can see from the Hook name, the purpose is to get the actual screen width. Code:

import { useEffect, useState } from 'react'; export function useScreenWidth(): number { const [width, setWidth] = useState(window.innerWidth); useEffect(() => { const handler = (event: any) => { setWidth(event.target.innerWidth); }; window.addEventListener('resize', handler); return () => { window.removeEventListener('resize', handler); }; } []); return width; }Copy the code

UseState and useEffect are Hooks built into React. UseState works by returning two values: a state value and a setter for it. Array deconstruction allows you to set the names of these two values to whatever you want.

and set

are common names. As a parameter, you pass in an initial value – in our case, the current screen width.

UseEffect is a hook function that takes two parameters as input: the first is the function to be called and the second is an array of Calling Objects. This means that we can pass many objects through the array, and effect will only be applied (or, in other words, the parameter function will be called) if at least one value in the array changes on the next render. For example. We can pass the following cases as the second argument:

  • No arguments at all – useEffect will be called every time you render.
  • [] – Because an empty array never changes, useEffect is only called on the first rendering
  • [arg1, arg2,… argN]- useEffect is called if any value inside the array is changed

With the second parameter, useEffect can mimic a class’s lifecycle method. For example. If we make [] the second argument, it will only be called on the first render, so it will mimic componentDidMount.

As mentioned above, hooks don’t think like classes, which is why there are no lifecycle methods at all, and hooks should not be looked at that way. UseEffect should be viewed more as a side effect. That’s why it’s fair to say that having [] as a second argument mimics componentDidMount and gives the same behavior, but it’s important to understand that the two are different.

Using Hooks as HOC

HOC is an advanced React technology for reusing component logic, which allows us to use Hook logic in existing class components. Because HOC is taking a component as input and returning the same component with some extra props. In our case, we would pass the Hook function as props.

import React from 'react'; import { useScreenWidth } from '.. /hooks/useScreenWidth'; export const withHooksHOC = (Component: any) => { return (props: any) => { const screenWidth = useScreenWidth(); return <Component width={screenWidth} {... props} />; }; };Copy the code

The final step is to simply wrap our existing class components with this HOC. Then, we just use the width property as the other property we pass to the component.

import React from 'react';
import { withHooksHOC } from './withHooksHOC';

interface IHooksHOCProps {
  width: number;
}

class HooksHOC extends React.Component<IHooksHOCProps> {
  render() {
    return <p style={{ fontSize: '48px' }}>width: {this.props.width}</p>;
  }
}

export default withHooksHOC(HooksHOC);
Copy the code

This does not violate any Hooks rules, because we are using the actual Hooks in the function – just as we should. Passing logic as props is also fine.

Using Hook as render prop

There is another way to achieve our goal:

import { FunctionComponent } from 'react'; import { useScreenWidth } from '.. /hooks/useScreenWidth'; type ScreenWidthChildren = (screenWidth: number) => any; interface IScreenWidthProps { children: ScreenWidthChildren; } export const ScreenWidth: FunctionComponent<IScreenWidthProps> = ({ children, }) => { const screenWidth: number = useScreenWidth(); return children(screenWidth); };Copy the code

Now we create a Function Component that takes children as an argument. After using Hook logic here, we return the desired result as a child function. After that, the logic is simple: import the created Function Component into your existing class and pass children down as the Render prop.

The last

Hooks are big changes in the React world and they will definitely change the way we think about React development. It may not seem that simple now, but over the next few years, class usage will gradually decline. I’m glad the React team didn’t force us to rewrite all projects and encouraged us to use Hooks with our classes. They are not going to discard class in the near future, so we certainly have time to try Hooks. Having a way to use the Hooks logic directly in a class, as shown in this article, is just one advantage of trying to use Hooks.

Original text: infinum co/the – capsize…

Finally, it is an advertisement. Recently, a new public account for sharing technology has been opened, and you are welcome to pay attention to 👇 (currently the number of followers is poor 🤕).