Adding react-to-print in your project
Tags: react, programming, tutorial, typescript
Published: 2021-10-15 15:43:49

In this blogpost I'll show an added feature in a project already created **My first project with React ts + Hooks** link to blogpost:

{% link https://dev.to/beatrizoliveira/my-first-project-with-react-ts-hooks-3mji %} 

## Step by Step
### 1 - Install Dependencies
```sh
# using yarn
yarn add react-to-print

# using npm
npm i react-to-print
```
### 2 - Flow of the new Feature:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dnmkdhgrzki10f50sa4.png)
An import concept is **Lifting State Up** which consists of: when we want to add one or more features/components for certain functionality and manage them so that they work together we use the concept of elevating state so that the root component will be the manager of all child components.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yg2sqihcc6cz9kbvhbtd.png)
See more in: https://reactjs.org/docs/lifting-state-up.html#gatsby-focus-wrapper

### 3 - Folder structure
To best understand and visualization:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fj4b7x00dpdh1v3zx5y.png)

### 4 - Add ActionButton
First, we will import all the dependencies that will be used and pass the type of the **componentToPrint** function to be used:

```ts
import React from "react";
import Button from "@material-ui/core/Button";
import ReactToPrint from "react-to-print";

type ActionButtonProps = {
  componentToPrint: React.MutableRefObject<null>;
};
```
And we create ActionButton function and we passed the componentToPrint function into the same, and return button print:

```ts
return (
    <>
      <ReactToPrint
        trigger={() => (
          <Button id={"print"} variant="contained" color="primary">
            {" "}
            {"Print"}{" "}
          </Button>
        )}
        content={() => componentToPrint.current}
      />
    </>
  );
```
We wrap the button with ReactToPrint and pass a trigger on it where the component will return and then an onClick.
How we will use the useRef hook to return mutable objects via ``.current`` and related components.

### 5 - We passed ComponentToPrint to TodoList component
We wrap the To component of the List with a div that links with componentToPrint:

```ts
return (
    <div ref={(el) => (componentToPrint.current = el)}>
      {list.map((item, index) => (
        <div key={item.id}>
          <TextField
            value={item.value}
            onChange={(e) => handleChange(e.currentTarget.value, item.id)}
          />
          <IconButton onClick={() => handleAdd(index)}>
            <AddIcon />
          </IconButton>

          {list.length > 1 && (
            <IconButton onClick={() => handleDelete(item.id)}>
              <DeleteIcon />
            </IconButton>
          )}
        </div>
      ))}
    </div>
  );
```
### 6 - Pass componentToPrint to component Root (App.tsx)
Coming to the last step we will pass the componentToprint on the parent component where it will manage the child components.

We pass the componentToPrint function inside the App function and we will use the useRef hook to finish the relation of all the components that are part of the buttonPrint and we pass the componentToPrint as a parameter in their return:

```ts
const App = () => {
  const componentToPrint = useRef(null);

  return (
    <div className="container">
      <TodoList componentToPrint={componentToPrint} />
      <ActionButton componentToPrint={componentToPrint} />
    </div>
  );
};
```
### Result

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93mfkjtk0ysjwia3qnyd.png)

🔗 GitHub: {% github https://github.com/beatrizoliveiira/todolist %}

🔗 CodeSandbox: https://codesandbox.io/s/react-to-print-f5tje?file=/src/App.tsx