I am working on a React project where I have two components, UserRules
(Component A) and UserEmail
(Component B). I need to pass the value of a state variable selectedVoucherOption
from Component A to Component B so that I can render specific data in Component B based on the selected option.
Here’s what I am doing:
In UserRules
(Component A), I’ve added Line A because I want to pass the value of selectedVoucherOption
to Component B (UserEmail
) to render the data conditionally based on the user's selection.
Component A:
function UserRules({ intl, home, dispatch }) {
const [selectedVoucherOption, setSelectedVoucherOption] = useState(null);
return (
<Row>
<Col xs={12}>
<Label required>{intl.formatMessage({ ...messages.voucherOptions.header })}</Label>
<Dropdown
options={voucherOptions}
placeholder={intl.formatMessage({ ...messages.voucherOptions.placeholder })}
onChange={(_evt, obj) => {
setSelectedVoucherOption(obj);
UserEmail; // Line A: Trying to pass the value here
}}
/>
</Col>
</Row>
);
}
Component B:
function UserEmail({ intl, onValueChange }) {
// Logic based on selectedVoucherOption
...
}
Email.propTypes = {
intl: intlShape.isRequired,
onValueChange: PropTypes.func.isRequired,
};
The problem I’m facing is figuring out how to pass the selectedVoucherOption state from Component A to Component B (at Line A) in a way that Component B can conditionally render data based on this value.
What’s the best way to achieve this in React?
Rendering a component happens in the JSX, not in a function. (Though a function can certainly be used to build JSX, but that function would have to build JSX and not simply reference a component function like you're attempting.)
For example:
<Dropdown
options={voucherOptions}
placeholder={intl.formatMessage({ ...messages.voucherOptions.placeholder })}
onChange={(_evt, obj) => {
setSelectedOption(obj);
}}
/>
<UserEmail />
Note the <UserEmail />
as a standalone element in the markup. You can conditionally include it by wrapping it in a conditional expression. For example:
<Dropdown
options={voucherOptions}
placeholder={intl.formatMessage({ ...messages.voucherOptions.placeholder })}
onChange={(_evt, obj) => {
setSelectedOption(obj);
}}
/>
{ someCondition ? <UserEmail /> : null }
Note that the JavaScript expression is wrapped in {}
to indicate that it is an expression and not JSX markup. Whatever condition you use as someCondition
would determine whether the expression evaluates to <UserEmail />
or null
.
If you want to pass a prop to it, you'd do that exactly like the props you're already passing to other components:
<Dropdown
options={voucherOptions}
placeholder={intl.formatMessage({ ...messages.voucherOptions.placeholder })}
onChange={(_evt, obj) => {
setSelectedOption(obj);
}}
/>
{ someCondition ? <UserEmail someProp={selectedVoucherOption} /> : null }
And in the component you'd read that prop:
function UserEmail({ intl, onValueChange, someProp }) {
// Logic based on someProp
}
Basically, the component you write is structurally no different from the 3rd party components you're already using. A component is a component either way. You'd include it in the JSX, conditionally or otherwise, and pass props to it like any other component.