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 argumentopropsicon={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
