I am able to use a React class component (i.e. React.Component
) as a Type but unable to use functional/stateless components. Here is an example:
import Footer from 'path/to/component/Footer';
interface ComponentProps {
customFooter: (Footer)
}
class MyComponent extends React.Component<ComponentProps> {
render() {
return (
<div>
{this.props.customFooter}
</div>
);
}
}
Footer.tsx
const Footer: React.StatelessComponent<{ children?: any }> = ({ children }) => (
<footer>
<div>
{children}
</div>
</footer>
);
export default Footer;
The red underline is under the (Footer)
and reads: Cannot find name 'Footer'
.
I've discovered that if I use a React class component instead of a functional component, my issue goes away. Why is it that I cannot use a functional component and is there a way for me to do so?
The consensus in the React community now seems to be that, you should avoid using React. FC because it causes the component to implicitly take children . This means the component will accept children, even if they're not supposed to.
Functional Components — functions that return JSX. Can do more stuff with React Hooks. Class Components — classes that can manipulate state, props, and lifecycle methods. Pure Components — functional components that performs shouldComponentUpdate() automatically.
From the sounds of things, it will eventually be deprecated in favor of the naming React. FunctionComponent once React 18 is released.
React recommends that Functional Components are used over classes, and even will throw warnings about a few Class Component lifecycle methods that are being deprecated.
Footer isn't a type it is only a variable, to get the type you could use typeof
const Footer: React.StatelessComponent<{ children?: any }> = ({ children }) => (
<footer>
<div>
{children}
</div>
</footer>
);
interface ComponentProps {
customFooter: typeof Footer
}
then you can use it like this:
class MyComponent extends React.Component<ComponentProps> {
render() {
const {customFooter: CustomFooter} = this.props;
return (
<div>
{<CustomFooter>footer children</CustomFooter>}
</div>
);
}
}
const MainComponent = () => {
return (<MyComponent customFooter={Footer}/>)
};
if you want to add an actual jsx element as value like this:
const MainComponent = () => {
return (<MyComponent customFooter={<Footer>footer children</Footer>}/>)
};
then you need to set the type of customFooter to something like React.ReactNode:
interface ComponentProps {
customFooter: React.ReactNode
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With