This content originally appeared on DEV Community and was authored by Francisco Mendes
I believe that if you are reading this article, you already have an idea of component hireraquia and the normal flow is to pass props from the parent component to the child component.
I believe we all had some friction trying to convert our JavaScript knowledge to TypeScript, even though it was the same the code became more verbose and suddenly you started questioning everything.
I continue with several challenges on a daily basis, however today I am fully aware of the advantages that TypeScript brings to my application development experience in React.
Exactly today I'm going to give a brief example of how we can pass props between components using TypeScript.
Let's code
Pretend that the main page of your application is as follows:
// @src/App.tsx
import React, { useState } from "react";
import Form from "./components/Form";
const App = () => {
const [state, setState] = useState("");
const handleOnSubmit = (e) => {
e.preventDefault();
console.log({ state });
};
return (
<Form
state={state}
setState={setState}
handleOnSubmit={handleOnSubmit}
placeholder="Type some letters"
/>
);
};
export default App;
And the component of our form is as follows:
// @src/components/Form.tsx
import React from "react";
const Form = ({
state,
setState,
handleOnSubmit,
placeholder,
}) => {
return (
<form onSubmit={handleOnSubmit}>
<input
type="text"
value={state}
onChange={(e) => setState(e.target.value)}
placeholder={placeholder}
/>
<button type="submit">Submit</button>
</form>
);
};
export default Form;
As you may have noticed both components, both are written the same way you would in JavaScript. And you may have noticed that we passed the following properties from the parent component to the child component:
-
state
is a string; -
setState
is a function; -
handleOnSubmit
is a function; -
placeholder
is a string;
But before that we have to type our own function components. This way:
// @src/App.tsx
const App: React.FC = () => {
// Hidden for simplicity
}
// @src/components/Form.tsx
const Form: React.FC = () => {
// Hidden for simplicity
}
So we can go to our Form.tsx
and create a type called Props that will be used as a generic for our component.
// @src/components/Form.tsx
import React from "react";
type Props = {
state: string;
setState: (val: string) => void;
handleOnSubmit: () => void;
placeholder: string;
};
const Form: React.FC<Props> = ({
state,
setState,
handleOnSubmit,
placeholder,
}) => {
return (
// Hidden for simplicity
);
};
export default Form;
You may have noticed an inconsistency in the previous code, in App.tsx
the handleOnSubmit function takes a single argument, which is an event.
While in our Props
type of Form.tsx
we don't have any arguments. For this we will use a React data type called FormEvent
that will have a generic, which in this case will be the HTMLFormElement
.
This way we will already have the ideal data type to "handle" the form event.Like this:
// @src/components/Form.tsx
import React, { FormEvent } from "react";
type SubmitEvent = FormEvent<HTMLFormElement>;
type Props = {
state: string;
setState: (val: string) => void;
handleOnSubmit: (e: SubmitEvent) => void;
placeholder: string;
};
const Form: React.FC<Props> = ({
state,
setState,
handleOnSubmit,
placeholder,
}) => {
return (
// Hidden for simplicity
);
};
export default Form;
This way, you must have also noticed that in the input element we have an attribute that is the onChange which is actually an event, so we have to type it.
In a very similar way to what we did before. First we will import a React data type called ChangeEvent
, then we will assign a generic which in this case will be HTMLInputElement
. This way:
// @src/components/Form.tsx
import React, { ChangeEvent, FormEvent } from "react";
type SubmitEvent = FormEvent<HTMLFormElement>;
type InputEvent = ChangeEvent<HTMLInputElement>;
// Hidden for simplicity
const Form: React.FC<Props> = ({
// Hidden for simplicity
}) => {
return (
<form onSubmit={handleOnSubmit}>
<input
type="text"
value={state}
onChange={(e: InputEvent) => setState(e.target.value)}
placeholder={placeholder}
/>
<button type="submit">Submit</button>
</form>
);
};
export default Form;
Now we can go back to our App.tsx
. We just need to create a type in the handleOnSubmit
function argument, which, as you might have guessed, is an event. Like this:
// @src/App.tsx
import React, { useState } from "react";
import Form from "./components/Form";
type FormEvent = React.FormEvent<HTMLFormElement>;
const App: React.FC = () => {
const [state, setState] = useState("");
const handleOnSubmit = (e: FormEvent) => {
e.preventDefault();
console.log({ state });
};
return (
// Hidden for simplicity
);
};
export default App;
Finally we can add a generic to our useState()
, which in this case is a string.
// @src/App.tsx
import React, { useState } from "react";
// Hidden for simplicity
const App: React.FC = () => {
const [state, setState] = useState<string>("");
// Hidden for simplicity
};
export default App;
Conclusion
As always, I hope I was clear and that I helped you. If you notice any errors in this article, please mention them in the comments. ✏️
Hope you have a great day! ? ?
This content originally appeared on DEV Community and was authored by Francisco Mendes
Francisco Mendes | Sciencx (2021-08-02T21:53:26+00:00) Passing Props to Child Components in React using TypeScript. Retrieved from https://www.scien.cx/2021/08/02/passing-props-to-child-components-in-react-using-typescript/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.