Categories
React Answers

Hoe to Register Event Handlers within the React useEffect Hook?

Sometimes, we want to registrar events listeners within the useEffect hook.

In this article, we’ll look at how to registrar events listeners within the useEffect hook.

Register Event Handlers within the React useEffect Hook

We can register events within the useEffect callback.

For instance, we can write:

const App = () => {
  const [userText, setUserText] = useState('');

  const handleUserKeyPress = useCallback(event => {
    const { key, keyCode } = event;
    if (keyCode === 32) {
      setUserText(prevUserText => `${prevUserText}${key}`);
    }
  }, []);

  useEffect(() => {
    window.addEventListener('keydown', handleUserKeyPress);

    return () => {
      window.removeEventListener('keydown', handleUserKeyPress);
    };
  }, [handleUserKeyPress]);

  return (
    <div>
      <p>{userText}</p>
    </div>
  );
}

We listen to the keypress event on the window.

If we press the space key, then the key code will be registered.

Then we can use that to append the state string with the key text.

We just keep appending the key code to the state string.

Conclusion

We can register events within the useEffect callback.

Categories
React Answers

How to React Hooks in a React Classic class Component

Sometimes, we want to use React hooks in a React class component.

In this article, we’ll look at how to use React hooks in a React class component.

Use React Hooks in a React Classic class Component

To use hooks in a class component, we can create a functional component that’s used as a higher-order component.

For instance, we can write:

const withHook = (Component) => {
  return WrappedComponent = (props) => {
    const someHookValue = useSomeHook();
    return <Component {...props} someHookValue={someHookValue} />;
  }
}

We used our useSomeHook hook in our withHook component.

Then we pass the hooks’s output value into the Component , which can be any component, including a class component.

Then we can use it by writing:

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

export default withHook(Foo);

We passed in Foo into our withHook higher-order component so that we can use our hook in the withHook HOC.

Conclusion

To use hooks in a class component, we can create a functional component that’s used as a higher-order component.

Categories
React Answers

How to add export to CSV button in a React table?

Sometimes, we want to add export to CSV button in a React table.

In this article, we’ll look at how to add export to CSV button in a React table.

How to add export to CSV button in a React table?

To add export to CSV button in a React table, we can use the react-csv library.

To install it, we run:

npm i react-csv

Then we add the button to the table by writing:

import React from "react";
import { useTable } from "react-table";
import { CSVLink } from "react-csv";

const csvData = [
  { firstName: "John", lastName: "Doe" },
  { firstName: "Jane", lastName: "Doe" }
];

const Table = ({ columns, data }) => {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({
    columns,
    data
  });

  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map((headerGroup) => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map((column) => (
              <th {...column.getHeaderProps()}>{column.render("Header")}</th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map((row, i) => {
          prepareRow(row);
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map((cell) => {
                return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
};

export default function App() {
  const columns = React.useMemo(
    () => [
      {
        Header: "Name",
        columns: [
          {
            Header: "First Name",
            accessor: "firstName"
          },
          {
            Header: "Last Name",
            accessor: "lastName"
          }
        ]
      }
    ],
    []
  );

  const data = React.useMemo(() => {
    return csvData.map((d) => Object.values(d));
  }, []);

  return (
    <>
      <CSVLink data={data}>Download me</CSVLink>
      <Table columns={columns} data={csvData} />;
    </>
  );
}

We create the Table component which calls the useTable hook with the columns and data props to return an object that has the properties we use to create the table.

Next, we add a CSV download link by using the CSVLink component.

We pass in a nested array as the value of the data prop so react-csv can generate the CSV from it.

We create the nested array by calling useMemo with a callback that returns the nested array which we create by calling csvData.map with a callback that returns the values in an array from each csvData entry with Object.values.

Now we should see a Download me button which we can click to download the CSV.

Conclusion

To add export to CSV button in a React table, we can use the react-csv library.

Categories
React Answers

How to add export to CSV button in a React table?

Sometimes, we want to add export to CSV button in a React table.

In this article, we’ll look at how to add export to CSV button in a React table.

How to add export to CSV button in a React table?

To add export to CSV button in a React table, we can use the react-csv library.

To install it, we run:

npm i react-csv

Then we add the button to the table by writing:

import React from "react";
import { useTable } from "react-table";
import { CSVLink } from "react-csv";

const csvData = [
  { firstName: "John", lastName: "Doe" },
  { firstName: "Jane", lastName: "Doe" }
];

const Table = ({ columns, data }) => {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({
    columns,
    data
  });

  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map((headerGroup) => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map((column) => (
              <th {...column.getHeaderProps()}>{column.render("Header")}</th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map((row, i) => {
          prepareRow(row);
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map((cell) => {
                return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
};

export default function App() {
  const columns = React.useMemo(
    () => [
      {
        Header: "Name",
        columns: [
          {
            Header: "First Name",
            accessor: "firstName"
          },
          {
            Header: "Last Name",
            accessor: "lastName"
          }
        ]
      }
    ],
    []
  );

  const data = React.useMemo(() => {
    return csvData.map((d) => Object.values(d));
  }, []);

  return (
    <>
      <CSVLink data={data}>Download me</CSVLink>
      <Table columns={columns} data={csvData} />;
    </>
  );
}

We create the Table component which calls the useTable hook with the columns and data props to return an object that has the properties we use to create the table.

Next, we add a CSV download link by using the CSVLink component.

We pass in a nested array as the value of the data prop so react-csv can generate the CSV from it.

We create the nested array by calling useMemo with a callback that returns the nested array which we create by calling csvData.map with a callback that returns the values in an array from each csvData entry with Object.values.

Now we should see a Download me button which we can click to download the CSV.

Conclusion

To add export to CSV button in a React table, we can use the react-csv library.

Categories
React Answers

How to fix the ‘Error “Error: A Route is only ever to be used as the child of element Routes” ‘ error with React Router v6?

Sometimes, we want to fix the ‘Error "Error: A Route is only ever to be used as the child of element Routes" ‘ error with React Router v6.

In this article, we’ll look at how to fix the ‘Error "Error: A Route is only ever to be used as the child of element Routes" ‘ error with React Router v6.

How to fix the ‘Error "Error: A Route is only ever to be used as the child of element Routes" ‘ error with React Router v6?

To fix the ‘Error "Error: A Route is only ever to be used as the child of element Routes" ‘ error with React Router v6, we should put Route components inside the Routes component.

For instance, we write

import { render } from "react-dom";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import Expenses from "./routes/expenses";
import Invoices from "./routes/invoices";

const rootElement = document.getElementById("root");
render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />} />
      <Route path="expenses" element={<Expenses />} />
      <Route path="invoices" element={<Invoices />} />
    </Routes>
  </BrowserRouter>,
  rootElement
);

to wrap Routes around the Route components.

Then we can use React Router normally.

Conclusion

To fix the ‘Error "Error: A Route is only ever to be used as the child of element Routes" ‘ error with React Router v6, we should put Route components inside the Routes component.