How do I name my React Component in Webpack export? - reactjs

I have tested a range of possible Webpack configurations to ensure my component is named when I build my React component. However, I am still met with this PropTypes error:
Warning: Failed prop type: The prop `name` is marked as required in `w`, but its value is `undefined`.
How do rename my component in an export so that this error would read:
Warning: Failed prop type: The prop `name` is marked as required in `CustomName`, but its value is `undefined`.
I'd like the reference to be customised instead of w. I'm finding Webpack's documentation to be a little unclear.

The reason this happens is because Webpack minifies your code such that the name of your component (which is just like any variable) is changed to a shorter version in order to make the bundle smaller.
You have to manually set this as a static property on your component:
const Customised = () => {
// Your component
}
Customised.displayName = "Customised"
You can often find plugins for your build tooling (e.g. babel, esbuild) to do this automatically.

Related

How to import a React proptypes typed component as type any into a React Typescript component

We have quite a big component library done in proptypes, and we are moving to typescript.
So when I was moving a .jsx component to be a .tsx component an imported .jsx component suddenly started throwing typing errors, there is nothing currently wrong with the imported component and I can't just rewrite it typescript as it is used everywhere and it would be more effort at the moment than worth.
to get around this I did as follows (lots of intervening code removed)
import MyReactComponent from 'path/to/component';
const FixedMyReactComponent: any = MyReactComponent;
return <FixedMyReactComponent/>
it works, my errors went away, but I find this to be irritating, I would instead like not to have to make a FixedMyReactComponent and set a type for it locally, and (as I already said) I don't want to put in the time right now to fix the fact that typescript isn't understanding my component, so instead I would like to find some way to globally tell typescript ignore type errors you get from a js / jsx and only report errors from .ts / .tsx.
I suppose it would be something like
declare module '*.jsx' {
var _: React.Component<any, any>;
export default _;
}
but that doesn't seem to have the effect I want.
move your proptypes to a type then you can just type your component.
import { FC } from 'react'
type FixedMyReactComponentProps = {
id: string;
name: string;
}
const FixedMyReactComponent: FC<FixedMyReactComponentProps> = ({name, id}) => {
...
}
But if you must type it as any. You declare the return type:
const FixedMyReactComponent = (): any => {
...
}
If you are time-constrained in doing the work now you could use // #ts-nocheck (added in TypeScript v3.7 for this exact use case) at the top of all your newly created .ts?(x) files and gradually remove them over time. This will type check NOTHING basically treating the file as javascript while exporting whatever explicit or implicit types are defined in the file. You may also want to loosen the compilerOptions something like this until you can tighten them later on.
If you do have some time to complete the conversion you could look into using the react-javascript-to-typescript-transform npm package from lyft. It is deprecated but seems to get the job done, at least for the prop-type to type conversions.
Starting with a simple js prototype example from react.
import PropTypes from 'prop-types';
class Greeting extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
Greeting.propTypes = {
name: PropTypes.string
};
Install the module...
npm install -g react-js-to-ts
Run this command to convert all js files to ts.
react-js-to-ts ./**/*.js
The package then replaces all files from js with prop-types into .tsx with prop interfaces.
type GreetingProps = {
name?: string
};
class Greeting extends React.Component<GreetingProps, {}> {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Works for functional components and class components. I am not sure how this behaves with state types or other non-typed code you may have in your component but this would be a good step forward. The state could easily be typed as any for the time being anyway. Also not sure how well this package performs with complex prototypes like PropTypes.shape and PropTypes.arrayOf.
If I were you I would verify all the changes, but any conversion errors should be very apparent via type errors. No need to use a fake js to ts component conversions. Even after running this code, if you run into too many type errors you can turn off strict mode and even add // #ts-nocheck where needed until your team has the bandwidth to address the bad types.
Honestly, I think this is the best approach, any other way of trying to trick the typescript compiler is gonna be more difficult and hacky than this or provide inconsistent types from your original prototype definitions.

Ignore certain console errors / warnings in React?

I have a huge number of console errors like this appearing in my app:
Warning: React does not recognize the textStyle prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase textstyle instead. If you accidentally passed it from a parent component, remove it from the DOM element.
Ideally I would fix the errors but sadly that's not possible as I'm using Styled System with Styled Components:
https://github.com/styled-system/styled-system/issues/1044
As a less than ideal workaround Id like to disable certain errors from the console for the development version of React. Can this be done?
Not sure if it matters but I'm using React Native Web.
You can override the console.warn method with your own function that filters out the warnings you want to ignore:
const consoleWarn = console.warn;
const SUPPRESSED_WARNINGS = ['arning text - I will n'];
console.warn = function filterWarnings(msg, ...args) {
if (!SUPPRESSED_WARNINGS.some((entry) => msg.includes(entry))) {
consoleWarn(msg, ...args);
}
};
console.warn('I\'ll appear as a warning');
console.warn('warning text - I will not');
I'm not sure which console method react is using internally, so you may need to do the same for console.info, console.log and console.error.
You can also just use the production version of react, which suppresses all warnings by default, but of course you can't pick and choose, you loose all warnings in that case.

WebStorm code inspection to detect when an unknown prop is passed to a React Component

My team really wants syntax highlighting in WebStorm when a component is called with a prop that isn't defined in that component's propTypes.
class MyComponent extends Component {
static propTypes = {foo: PropType.string};
...
}
...
<MyComponent
bar={...} // this line would be marked as a warning/error
foo={"some string"}
/>
Is it possible to create a custom code inspection to perform this? How would we go about it?
WebStorm already offers prop name completion, and warns if a required prop is not being passed, so it seems like all of the necessary information already exists. (See the "Completing component properties" section of React - Help | WebStorm.)
Side note: obviously this wouldn't catch props passed dynamically (e.g. <MyComponent {...someObject} />), but we consider that an anti-pattern anyway.

React, warning 'css' is defined but never used no-unused-vars

I'm working to import CSS files in my React App. I have css being imported successfully like so:
Original source app: https://github.com/timscott/react-devise-sample
MainLayout.jsx
import css from '../styles/base.css'
base.css
body {
opacity: .1;
}
When I load my app in a browser I see the styles taking effect. The problem is, in the console I'm getting a JS warning:
webpackHotDevClient.js:198 ./src/layouts/MainLayout.jsx
.../client/src/layouts/MainLayout.jsx
12:8 warning 'css' is defined but never used no-unused-vars
✖ 1 problem (0 errors, 1 warning)
What am I doing wrong in React to cause the CSS to render but still get a warning in the console?
Name this "component" only if you need call them in some part of the code. e.g. Using CSS-Modules. This is only a regular css so load in this manner :
import '../styles/base.css'
But if you still want to keep this unused var you can edit your es-lint, and delete this rule. (Not Recommended)
You do not need "css from" since the css file is already connected to the jsx file. You only do that when using other jsx components, for example:
import SomeComponent from '../SomeComponent.jsx'

React, Material UI, JSPM and Babel : Error: Can't add property context, object is not extensible

I am trying to setup Material UI for React, using JSPM and ES6 through Babel.
1) installed material-ui with jspm install material-ui=npm:material-ui
2) this gave me the ability to import material ui into my React Component files like this : import {TextField, LeftNav} from 'material-ui'
At this point I get the right references into my ES6 file, so if I do a
console.log(TextField);
I get the react component printed.
Sadly my current issue is that I'm getting errors when trying to use the component in jsx
return (
<div>
<TextField />
</div>
)
throws an error :
Warning: getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.
warning.js:17 Warning: Something is calling a React component directly. Use a factory or JSX instead. See: http://fb.me/react-legacyfactory
warning.js:26 Warning: TextField(...): No `render` method found on the returned component instance: you may have forgotten to define `render` in your component or you may have accidentally tried to render an element whose type is a function that isn't a React component.
warning.js:17 Warning: Don't set the props property of the component. Mutate the existing props object instead.
dashboard:1 Uncaught (in promise) Error: Can't add property context, object is not extensible
Error loading http://localhost:3000/app.js
at ReactCompositeComponentMixin.mountComponent
Based on the warnings, I'm thinking that the error may be caused by a specific situation created by the combination of tools, Babel+JSPM+Material-UI.
Check the version of react you're running. It should be v0.13.3.
More info can be found here: https://github.com/callemall/material-ui/issues/1303

Resources