In React Typescript, let's say I have this function component:
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
interface testFCProps {
var1: string;
var2: string;
var3?: string;
}
const TestFC: React.FC<testFCProps> = (props: testFCProps) => {
useEffect(() => {
console.log('testFC use effect');
});
return (
<div>
here are my vars: {props.var1}, {props.var2}, {props.var3}.
</div>
);
};
I can display it in a React app, using JSX syntax:
const displayDiv = <TestFC var1="hello" var2="there" var3="general-kenobi" />;
ReactDOM.render(
<React.StrictMode>{displayDiv}</React.StrictMode>,
document.getElementById('root')
);
Result in-browser: here are my vars: hello, there, general-kenobi.
However, if I try to create displayDiv
using function syntax, like so:
const displayDiv = TestFC({
var1: 'hello',
var2: 'there',
var3: 'general-kenobo',
});
I get in-browser Error: Invalid hook call
. I am pretty sure I am using useEffect
hook properly here. If I comment it out, there is no error, so I don't think there is an issue inherent to creating function components with a function call.
Why is the creation of a function component using a function, and hooks, appear to be in conflict?
CodePudding user response:
Normally, function components get called by react in the middle of the rendering process. In your case, you're calling the function at a time when rendering is not taking place, which is causing the error. React has to do a bit of setup work before hand to let hooks like useEffect
do their thing, and that hasn't happened for your case.
If you just want to avoid the JSX syntax, you can do that, but you need to use equivalent code. The equivalent of <TestFC var1="hello" var2="there" var3="general-kenobi" />
isn't the function call you tried, but rather this:
const displayDiv = React.createElement(TestFC, {
var1: 'hello',
var2: 'there',
var3: 'general-kenobo',
})
createElement
returns an object describing what you want to be on the page, but doesn't actually call TestFC
yet. Later on, when rendering happens, react will look at the displayDiv
object, set things up, and call the component function for you.