Búsqueda de sitios web

reactjs - Verifica el método render de ForwardRef


Uso exactamente el código tal como se define en el ejemplo de https://material-ui.com/components/bottom-navigation/:

// saved in app.tsx:

import React from 'react';

import { makeStyles } from '@material-ui/core/styles';
import BottomNavigation from '@material-ui/core/BottomNavigation';
import BottomNavigationAction from '@material-ui/core/BottomNavigationAction';
import FolderIcon from '@material-ui/icons/Folder';
import RestoreIcon from '@material-ui/icons/Restore';
import FavoriteIcon from '@material-ui/icons/Favorite';
import LocationOnIcon from '@material-ui/icons/LocationOn';

const useStyles = makeStyles({
  root: {
    width: 500,
  },
});


export default function LabelBottomNavigation() {
  const classes = useStyles();
  const [value, setValue] = React.useState('recents');

  const handleChange = (event: React.ChangeEvent<{}>, newValue: string) => {
    setValue(newValue);
  };

  return (
    <BottomNavigation value={value} onChange={handleChange} className={classes.root}>
      <BottomNavigationAction label="Recents" value="recents" icon={<RestoreIcon />} />
      <BottomNavigationAction label="Favorites" value="favorites" icon={<FavoriteIcon />} />
      <BottomNavigationAction label="Nearby" value="nearby" icon={<LocationOnIcon />} />
      <BottomNavigationAction label="Folder" value="folder" icon={<FolderIcon />} />
    </BottomNavigation>
  );
}

Sin embargo, al usar este componente en index.tsx:

// saved in index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App/>
  </React.StrictMode>,
  document.getElementById('root'),
);

Obtengo este error:

Unhandled Runtime Error

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `ForwardRef(BottomNavigationAction)`.

Mi package.json:

{
  "scripts": {
    "start": "snowpack dev",
    "build": "snowpack build",
    "test": "web-test-runner \"src/**/*.test.tsx\"",
    "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",
    "lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx}\""
  },
  "dependencies": {
    "@material-ui/core": "^4.11.3",
    "@material-ui/icons": "^4.11.2",
    "react": "^17.0.0",
    "react-dom": "^17.0.0"
  },
  "devDependencies": {
    "@snowpack/plugin-dotenv": "^2.0.5",
    "@snowpack/plugin-react-refresh": "^2.4.0",
    "@snowpack/plugin-typescript": "^1.2.0",
    "@snowpack/web-test-runner-plugin": "^0.2.0",
    "@testing-library/react": "^11.0.0",
    "@types/chai": "^4.2.13",
    "@types/mocha": "^8.2.0",
    "@types/react": "^17.0.0",
    "@types/react-dom": "^17.0.0",
    "@types/snowpack-env": "^2.3.2",
    "@web/test-runner": "^0.12.0",
    "chai": "^4.2.0",
    "css-loader": "^5.2.0",
    "prettier": "^2.0.5",
    "snowpack": "^3.0.1",
    "ts-loader": "^8.1.0",
    "typescript": "^4.0.0"
  }
}

¿Cuál es la razón de este error y cómo puedo solucionarlo?

Respuesta #1

La parte crucial del error no es la parte **Verifica el método render de ForwardRef(BottomNavigationAction). **. Esto solo te indica dónde buscar el error.

La parte importante del error es:

Error: El tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase/función (para componentes compuestos) pero se obtuvo: objeto.

Esto suele ocurrir cuando no pasas un componente de React de la manera correcta. A menudo me encontré con este error al pasar componentes de íconos de la manera incorrecta.

Por ejemplo, en lugar de icon={<RestoreIcon />}, pasaría icon={RestoreIcon}. Sin embargo, parece que estás pasando los iconos de la manera correcta.

El icon tiene que ser un llamado ReactNode. Su tipo en Typescript es:

type ReactNode = ReactElement | string | number | ReactFragment | ReactPortal | boolean | null | undefined;

Así que al recibir un object se producirá un error.

Comparto diferentes formas en las que podrías pasar un componente:

  • icon={<RestoreIcon />}
  • icon={RestoreIcon}
  • icon={RestoreIcon()} se quejará de que falta el argumento props
  • icon={props => <RestoreIcon {...props} />}

Respuesta #2

esto se debe a que usar <React.StrictMode> elimina <React.StrictMode> y prueba de nuevo

// guardado en index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
    <App/>,
  document.getElementById('root'),
);

demostración

Artículos relacionados