Reputation: 577
I have a child functional component 'Display'. Which contains two buttons. The buttons toggle a state between true or false.
I want to pass this boolean value back to the parent container (component).
I then want to pass this boolean value to another child functional component called 'DisplayTitle'. Based on the boolean value I want to just update a string prop that gets rendered in the functional component.
I am slightly new to this. Should I be using redux or is there a more simple way of doing this? Thanks
Haven't yet
'Display' child component:
import * as React from 'react';
import Button from 'react-bootstrap/Button';
import Col from 'react-bootstrap/col';
interface Props {
buttonOneLabel: string;
buttonTwoLabel: string;
}
const Display = ({
buttonOneLabel,
buttonTwoLabel,
}: Props) => {
const [state, setVariant] = React.useState({ status: true });
return (
<>
<Col md="auto">
<Button
onClick={() => setVariant({ status: true })}
variant={state.status ? 'primary' : 'outline-primary'}
>
{buttonOneLabel}
</Button>
<Button
onClick={() => setVariant({ status: false })}
variant={state.status ? 'outline-primary' : 'primary'}
>
{buttonTwoLabel}
</Button>
</Col>
</>
);
};
export default Display;
'DisplayTitles' child component:
import * as React from 'react';
import Col from 'react-bootstrap/col';
interface Props {
title: string;
}
const DisplayTitles = ({
title,
}: Props) => (
<>
<Col>
<h3>{title}</h3>
</Col>
</>
);
export default DisplayTitles;
Parent component
import * as React from 'react';
import Jumbotron from 'react-bootstrap/Jumbotron';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/row';
import Title from './Title';
import SearchBy from './SearchBy';
import QuickSearch from './QuickSearch';
import Dates from './Dates';
import Display from './Display';
import DisplayTitle from './DisplayTitle';
import RunReport from './RunReport';
import AdvancedSearch from './AdvancedSearch';
import Options from './Options';
const Header = () => (
<div className="daily-sales-header">
<Jumbotron>
<Container fluid>
<Title
title="Daily Sales"
subTitle="(Single Page)"
/>
<Row>
<SearchBy
colClass="search-by-col"
buttonId="search-by-button"
buttonLabel="Search by"
/>
<QuickSearch
buttonLabel="Quick Search"
eleClass="quick-search"
eleIdBtn="quick-search-button"
/>
<Dates
fromClass="from-date"
fromLabel="From"
toClass="to-date"
toLabel="To"
/>
<Display
buttonOneLabel="Department"
buttonTwoLabel="Sub-Department"
onSelectLanguage={handleVari}
/>
<RunReport
buttonLabel="Run Report"
/>
</Row>
<Row>
<AdvancedSearch
buttonClass="adv-search-btn pull-right"
buttonLabel="Advanced Search"
/>
</Row>
</Container>
</Jumbotron>
<Row>
<DisplayTitle
title="Department Sales"
/>
<Options />
</Row>
</div>
);
export default Header;
Upvotes: 1
Views: 66
Reputation: 11848
Lifting state up is the most simple approach here.
Parent component will hold state for all children components and pass 1. Values as props 2. Callbacks so children may change values
Example (not tested, use as hint only)
const Header = () => {
const [state, setVariant] = React.useState({ status: true });
return <div className="daily-sales-header">
/* ... */
<Display
uttonOneLabel="Department"
buttonTwoLabel="Sub-Department"
onSelectLanguage={handleVari}
setVariant={setVariant.bind(this)}
status={state.status}
/>
/* ... */
<DisplayTitle
title="Department Sales"
status={state.status}
/>
<Options />
</Row>
</div>
}
Disply component will be
import * as React from 'react';
import Button from 'react-bootstrap/Button';
import Col from 'react-bootstrap/col';
interface Props {
buttonOneLabel: string;
buttonTwoLabel: string;
status: boolean;
setVariant: (status: {status: boolean}) => void;
}
const Display = ({
buttonOneLabel,
buttonTwoLabel,
status,
setVariant
}: Props) => {
return (
<>
<Col md="auto">
<Button
onClick={setVariant.bind(this, { status: true })}
variant={status ? 'primary' : 'outline-primary'}
>
{buttonOneLabel}
</Button>
<Button
onClick={setVariant.bind(this, { status: false })}
variant={status ? 'outline-primary' : 'primary'}
>
{buttonTwoLabel}
</Button>
</Col>
</>
);
};
export default Display;
Display titles will be
// ...
interface Props {
title: string;
status: boolean;
}
const DisplayTitles = ({
title,
status
}: Props) => (
<>
<Col>
<h3>{title}</h3>
<h3>{status}</h3>
</Col>
</>
);
// ...
As a result, when you click button in Display
component, setVariant
from parent component will be called. It updates status
in parent which will be immedeately propagated as props to both Display
and DisplayTitles
Upvotes: 1