Categories
React Answers

How to Fix the “Warning: Use the ‘defaultValue’ or ‘value’ props on select instead of setting ‘selected’ on option” Error Message in React?

Sometimes, we may encounter the “Warning: Use the ‘defaultValue’ or ‘value’ props on <select> instead of setting ‘selected’ on <option>” error message when we’re developing React apps.

In this article, we’ll look at how to fix the “Warning: Use the ‘defaultValue’ or ‘value’ props on <select> instead of setting ‘selected’ on <option>” error message when we’re developing React apps.

Fix the “Warning: Use the ‘defaultValue’ or ‘value’ props on <select> instead of setting ‘selected’ on <option>” Error Message in React

To fix the “Warning: Use the ‘defaultValue’ or ‘value’ props on <select> instead of setting ‘selected’ on <option>” error message when we’re developing React apps, we should set the defaultValue prop to the value attribute value of the default option.

For instance, we write:

import React from "react";

export default function App() {
  return (
    <select defaultValue="">
      <option value="" disabled>
        Choose a salutation ...
      </option>
      <option value="1">Mr</option>
      <option value="2">Mrs</option>
      <option value="3">Ms</option>
      <option value="4">Miss</option>
      <option value="5">Dr</option>
    </select>
  );
}

to set the defaultValue prop to an empty string, which matches the value attribute of the first option.

If defaultValue value matches the value attribute value of an option element, then that one will be selected by default.

This should be used instead of adding the selected attribute onto the option element that we want to select by default.

Conclusion

To fix the “Warning: Use the ‘defaultValue’ or ‘value’ props on <select> instead of setting ‘selected’ on <option>” error message when we’re developing React apps, we should set the defaultValue prop to the value attribute value of the default option.

Categories
React Answers

How to Add Custom HTML Attributes in React?

Sometimes, we want to add custom HTML attributes in React.

In this article, we’ll look at how to add custom HTML attributes in React.

Add Custom HTML Attributes in React

To add custom HTML attributes in React, we can just add them as we do with regular HTML element attributes.

For instance, we can write:

import React from "react";

export default function App() {
  return <div custom-attribute="some-value" />;
}

We just add the custom-attribute custom attribute and it’ll be rendered in the HTML.

This works since React 16.

Conclusion

To add custom HTML attributes in React, we can just add them as we do with regular HTML element attributes.

Categories
React Answers

How do to Wrap a React Component that Returns Multiple Table Rows and Avoid the “tr cannot appear as a child of div” Error?

Sometimes, we may see the “<tr> cannot appear as a child of <div>” error in React when we wrap a div around a table row.

In this article, we’ll look at how to fix the “<tr> cannot appear as a child of <div>” error in React.

Fix the “<tr> Cannot Appear as a Child of <div>” Error

To fix the “<tr> cannot appear as a child of <div>” error in React, we should remove the wrapper div.

For instance, we can write:

import React from "react";

const data = [
  { firstName: "jane", lastName: "smith" },
  { firstName: "john", lastName: "doe" },
  { firstName: "may", lastName: "wong" }
];

const Rows = data.map((d) => {
  return (
    <tr key={d.firstName}>
      <td>{d.firstName}</td>
      <td>{d.lastName}</td>
    </tr>
  );
});

export default function App() {
  return (
    <table>
      <thead>
        <tr>
          <th>first name</th>
          <th>last name</th>
        </tr>
      </thead>
      <tbody>{Rows}</tbody>
    </table>
  );
}

to create the Rows array, which has the JSX for the tr elements that we created by mapping them from the data array with map .

Then we pass that straight into the tbody to render the array of table rows.

Conclusion

To fix the “<tr> cannot appear as a child of <div>” error in React, we should remove the wrapper div.

Categories
React Answers

How to Capture the Last Character of Text Entered with onChange in React?

Sometimes, we want to capture the last character of text entered with onChange in React.

In this article, we’ll look at how to capture the last character of text entered with onChange in React.

Capture the Last Character of Text Entered with onChange in React

To capture the last character of text entered with onChange in React, we can use the useEffect hook to watch for the entered value.

For instance, we can write:

import React, { useEffect, useState } from "react";

export default function App() {
  const [name, setName] = useState("");

  useEffect(() => {
    console.log(name);
  }, [name]);

  return <input onChange={(e) => setName(e.target.value)} />;
}

We set the onChange to a function that calls setName with the e.target.value property, which has the value entered into the input.

Then we watch the name state for changes with the useEffect hook with an array with the name state inside as the 2nd argument.

Then we log the name value in the callback.

The console log should should the whole string that’s been entered

Conclusion

To capture the last character of text entered with onChange in React, we can use the useEffect hook to watch for the entered value.

Categories
React Answers

How to Add Table Rows that are Selectable on Click with React Table?

Sometimes, we want to add table rows that are selectable on click with React Table

In this article, we’ll look at how to add table rows that are selectable on click with React Table.

Add Table Rows that are Selectable on Click with React Table

To add table rows that are selectable on click with React Table, we can customize the columns to add a checkbox to the left of the other items.

Then we can pass props to that to make it select the rows.

For instance, we can write:

import React from "react";
import { useTable, useRowSelect } from "react-table";
import namor from "namor";

const range = (len) => {
  const arr = [];
  for (let i = 0; i < len; i++) {
    arr.push(i);
  }
  return arr;
};

const newPerson = () => {
  return {
    firstName: namor.generate({ words: 1, numbers: 0 }),
    lastName: namor.generate({ words: 1, numbers: 0 }),
    age: Math.floor(Math.random() * 30)
  };
};

const makeData = (...lens) => {
  const makeDataLevel = (depth = 0) => {
    const len = lens[depth];
    return range(len).map((d) => {
      return {
        ...newPerson(),
        subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined
      };
    });
  };

return makeDataLevel();
};

const IndeterminateCheckbox = React.forwardRef(
  ({ indeterminate, ...rest }, ref) => {
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

React.useEffect(() => {
      resolvedRef.current.indeterminate = indeterminate;
    }, [resolvedRef, indeterminate]);

    return (
      <>
        <input type="checkbox" ref={resolvedRef} {...rest} />
      </>
    );
  }
);

function Table({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    selectedFlatRows,
    state: { selectedRowIds }
  } = useTable(
    {
      columns,
      data
    },
    useRowSelect,
    (hooks) => {
      hooks.visibleColumns.push((columns) => [
        {
          id: "selection",

          Header: ({ getToggleAllRowsSelectedProps }) => (
            <div>
              <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
            </div>
          ),

Cell: ({ row }) => (
            <div>
              <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
            </div>
          )
        },
        ...columns
      ]);
    }
  );

  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.slice(0, 10).map((row, i) => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map((cell) => {
                  return (
                    <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <p>Selected Rows: {Object.keys(selectedRowIds).length}</p>
      <pre>
        <code>
          {JSON.stringify(
            {
              selectedRowIds: selectedRowIds,
              "selectedFlatRows[].original": selectedFlatRows.map(
                (d) => d.original
              )
            },
            null,
            2
          )}
        </code>
      </pre>
    </>
  );
}

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

  const data = React.useMemo(() => makeData(10, 3), []);

  return <Table columns={columns} data={data} />;
}

We create some data with the makeData function, which calls newPerson to return some randomly generated data.

Then we create the IndeterminateCheckbox component that renders a checkbox that is assigned the ref that we get from the 2nd parameter.

We also pass in the rest props from the first parameter.

This will let us select rows with the checkbox.

Then in the Table component, we render the data.

We set the Header property to a function that renders the IndeterminateCheckbox with the props that we get from getToggleAllRowProps .

Likewise, we set the Cell property to a function that renders the IndeterminateCheckbox with the props that we get from getToggleRowSelectedProps .

We put that before columns so that it’ll be rendered on the leftmost column.

Then in the return statement, we render the table contents.

selectedRowIds has the IDs of the selected row.

And selectedFlatRows has the data of the selected rows.

Conclusion

To add table rows that are selectable on click with React Table, we can customize the columns to add a checkbox to the left of the other items.

Then we can pass props to that to make it select the rows.