Reputation: 1547
In React we can pass data between class based components using states and props in the following manner:
App.js
import Name from './Name';
import React, { Component } from 'react'
export class App extends Component {
state = {
name: "Tarun"
}
render() {
return (
<Name name={this.state.name}/>
)
}
}
export default App
Name.js
import React, { Component } from 'react'
export class Name extends Component {
render() {
return (
<div>
My name is : {this.props.name}
</div>
)
}
}
export default Name
But now since React has introduced functional components what is the equivalent code if I use functional components for both App.js
and Name.js
?
Upvotes: 28
Views: 55645
Reputation:
If you use React v17+ with TypeScript & functional components in React.StrictMode
, then:
1) Parent to Child
1.1) Parent Component, e.g. App.tsx
import Dashboard from "./components/Dashboard/Dashboard";
export default function App() {
return <Dashboard title="My Dashboard"></Dashboard>;
}
1.2) Child Component, e.g. Dashboard
// src/components/Dashboard/Dashboard.tsx
import React from "react";
type DashboardProps = {
title: string;
};
const Dashboard: React.FC<DashboardProps> = (props) => (
<div>Dashboard Component {props.title}</div>
);
export default Dashboard;
This is the same as above (excerpt):
//..
export default function Dashboard(props: DashboardProps) {
return <div>Dashboard Component {props.title}</div>;
}
Lazy-Loading
If you want to use "Lazy-Loading", you have to change the Dashboard component slightly or maybe use a Dashboard.lazy.tsx
like:
import React, { lazy, Suspense } from 'react';
import { DashboardProps } from '../../Types';
const LazyDashboard = lazy(() => import('./Dashboard'));
const Dashboard = (props: DashboardProps) => (
<Suspense fallback={null}>
<LazyDashboard {...props} />
</Suspense>
);
export default Dashboard;
I've moved the
DashboardProps
into a new file due to reusability.
// Types/index.tsx
export type DashboardProps = {
title: string;
};
2) Child to Parent (this time with React.useState hook)
2.1) Parent, e.g. App.tsx
import Dashboard from "./components/Dashboard/Dashboard";
export default function App() {
const [messageFromChild, getMessageFromChild] = React.useState(
"Dad is waiting"
);
const sendDataToParent = (message: string) => {
getMessageFromChild(message);
};
return (
<div>
<Dashboard
props={{ title: "My Dear Dashboard" }}
sendDataToParent={sendDataToParent}
></Dashboard>
<div>
<strong>From Child to Parent:</strong> {messageFromChild}
</div>
</div>
);
}
2.2) Child, e.g. Dashboard.tsx
import React from "react";
import { DashboardProps } from "../../Types";
const Dashboard: React.FC<DashboardProps> = ({ props, sendDataToParent }) => (
<div>
<strong>From Parent to Child:</strong> {props.title}
<button
onClick={() => {
sendDataToParent("Hi Dad");
}}
>
Send to Parent
</button>
</div>
);
export default Dashboard;
2.3) Types, e.g. Types/index.tsx
export type DashboardProps = {
props: {
title: string;
};
sendDataToParent: (message: string) => void;
};
Upvotes: 9
Reputation: 996
You should use useState
hook for state management in functional components as follows:
import React, { useState } from "react";
export default function App() {
const [name, setName] = useState("Tarun");
return (
<div>
<Name name={name}/>
</div>
);
}
//Name
export default function Name(props) {
return (
<div>
My name is : {props.name}
</div>
);
}
Upvotes: 0
Reputation: 15166
For Name.jsx
you could do something like the following:
import React from 'react';
// additionally you can do destructuring with props like this:
// const Name = ({name}) => {
const Name = (props) => {
return (
<div>
My name is : {props.name}
</div>
);
}
export default Name;
Passing props
happens at creation time of the functional component just like above. As the React documentation states:
This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “function components” because they are literally JavaScript functions.
You can read further here: Function and Class Components
For App.jsx
let me suggest the following example:
import Name from './Name';
import React, { useState } from 'react';
const App = () => {
const [name, setName] = useState('Tarun');
return (
<Name name={name}/>
)
}
export default App;
From the above example useState
function is the state hook what helps you create state object in your App.jsx
functional component and for further updates you can use the setName
function additionally for example on a click event. From the documentation:
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
Please refer this link Using the State Hook.
I hope this helps!
Upvotes: 5
Reputation: 43
App.js
import Name from './Name';
import React, {useState} from 'react'
export function App(){
const [name, setName] = "Tarun";
return <Name name={name}>;
}
Name.js
import React, { Component } from 'react'
export function Name({name}){
return <div>My name is : {name} </div>
}
There you go.
Upvotes: 0
Reputation: 63524
Using hooks you could write something like this.
In App
:
import React, { useState } from 'react'
export default function App() {
// `useState` returns an array with the state
// and the method used to update the state
// You can initialise the state with a variable/object
const [name, setName] = useState('Tarun');
// No need for a render method
// Just return the JSX from the function
return <Name name={name} />;
}
In Name
:
import React from 'react'
// Props are passed down like normal function args
// Destructure `names` from the props object
export default function Name({ name }) {
return <div>My name is: {name}</div>;
}
Upvotes: 23