ReactJs:如何将数据从一个组件传递到另一个组件?
ReactJs: How to pass data from one component to another?
如果组件中的两张或更多卡片被 selected 如何将数据传递给按钮组件?
我有一个包含两个组件的登录页面;模板列表和一个按钮。
<TemplateList templates={templates} />
<MenuButton style={actionButton} onClick={onOnboardingComplete}>
Select at least 2 options
</MenuButton>
TemplateList 为我的模板带来了一系列信息,并用它创建了模板卡。然后我可以 select 我的卡片并取消 select 它们。
我的按钮在按下时会带我进入入职的下一步。
我想知道我应该如何连接这两个组件。我的按钮现在是灰色的,希望发生这种情况:
1.按钮是灰色的,用户无法继续下一步,直到 select 两张或更多卡片。
2。当两张或更多卡片被 selected 时,按钮变为蓝色,他们可以按下按钮继续。
这是我的模板列表:
export type Template = {
title: string;
description: string;
imgURL: string;
id?: number;
};
type Props = {
templates: Template[];
};
const TemplateList = ({ templates }: Props) => {
return (
<div className={styles.scrollContainer}>
{templates.map((item) => (
<TemplateCard
title={item.title}
description={item.description}
img={item.imgURL}
classNameToAdd={styles.cardContainer}
key={item.id}
/>
))}
</div>
);
};
export default TemplateList;
这是我的模板卡:
type Props = {
title: string;
description: string;
img: string;
classNameToAdd?: string;
classNameOnSelected?: string;
};
const TemplateCard = ({ title, description, img, classNameToAdd, classNameOnSelected }: Props) => {
const { aspectRatio, vmin } = useWindowResponsiveValues();
let className = `${styles.card} ${classNameToAdd}`;
const [selected, setSelected] = useState(false);
const handleClick = () => {
setSelected(!selected);
};
if (selected) {
className += `${styles.card} ${classNameToAdd} ${classNameOnSelected}`;
}
return (
<div style={card} className={className} onClick={handleClick}>
<img style={imageSize} src={img}></img>
<div style={cardTitle}>
{title}
{selected ? <BlueCheckIcon style={blueCheck} className={styles.blueCheck} /> : null}
</div>
<div style={descriptionCard}>{description}</div>
</div>
);
};
TemplateCard.defaultProps = {
classNameOnSelected: styles.selected,
};
export default TemplateCard;
这是现在的样子。
至少有 3 种方法可以实现您的要求:
选项 1
将 Button 组件放入 <TemplateList>
组件
添加一个 useState
绑定到 <TemplateList>
组件以保存数量
已选择的卡片
添加两个新道具 onSelectCard
和 onDeselectCard
到 <TemplateCard>
到 increment/decrement 由 1
为每个 selected/deselected 项
在 <TemplateList
组件内实现回调函数(代码如下)
需要时在<TemplateCard>
中调用onSelectCard
(代码如下)
模板列表组件
const TemplateList = ({ templates }: Props) => {
const [noOfSelectedCards, setNoOfSelectedCards] = useState(0);
handleSelect = () => setNoOfSelectedCards(noOfSelectedCards + 1);
handleDeselect = () => setNoOfSelectedCards(noOfSelectedCards - 1);
return (
<div classNae="template-list-container">
<div className={styles.scrollContainer}>
{templates.map((item) => (
<TemplateCard
title={item.title}
description={item.description}
img={item.imgURL}
classNameToAdd={styles.cardContainer}
key={item.id}
onSelectCard={handleSelect}
onDeselectCard={handleDeselect}
/>
))}
</div>
<MenuButton style={actionButton} onClick={onOnboardingComplete} className={noOfSelectedCards === 2 ? 'active' : ''}>
Select at least 2 options
</MenuButton>
</div>
);
};
TemplateCard组件
const TemplateCard = ({ ..., onSelectCard, onDeselectCard }: Props) => {
...
const [selected, setSelected] = useState(false);
const handleClick = () => {
if(selected) {
onDeselectCard();
} else {
onSelectCard();
}
setSelected(!selected);
};
...
};
现在,您将在您的状态 noOfSelectedCards
(<TemplateList>
组件)中拥有当前所选卡片的数量,因此您可以有条件地呈现任何 className
您想要的按钮或用它做点别的事。
选项 2
使用React Context在组件之间共享状态
在这种情况下使用 React Context 是可以的,但是如果您的要求包含应用程序中组件之间 handling/sharing 状态的其他类似情况,我建议您看一下第三个选项。
选项 3
使用 Redux 之类的状态管理来处理组件之间的 global/shared 状态。
对于跨应用程序共享状态非常普遍且重要的项目,这可能是最佳选择。您需要一些时间来了解有关 Redux 的概念,但在您了解之后,我向您保证您会喜欢使用它。
如果组件中的两张或更多卡片被 selected 如何将数据传递给按钮组件?
我有一个包含两个组件的登录页面;模板列表和一个按钮。
<TemplateList templates={templates} />
<MenuButton style={actionButton} onClick={onOnboardingComplete}>
Select at least 2 options
</MenuButton>
TemplateList 为我的模板带来了一系列信息,并用它创建了模板卡。然后我可以 select 我的卡片并取消 select 它们。
我的按钮在按下时会带我进入入职的下一步。
我想知道我应该如何连接这两个组件。我的按钮现在是灰色的,希望发生这种情况:
1.按钮是灰色的,用户无法继续下一步,直到 select 两张或更多卡片。
2。当两张或更多卡片被 selected 时,按钮变为蓝色,他们可以按下按钮继续。
这是我的模板列表:
export type Template = {
title: string;
description: string;
imgURL: string;
id?: number;
};
type Props = {
templates: Template[];
};
const TemplateList = ({ templates }: Props) => {
return (
<div className={styles.scrollContainer}>
{templates.map((item) => (
<TemplateCard
title={item.title}
description={item.description}
img={item.imgURL}
classNameToAdd={styles.cardContainer}
key={item.id}
/>
))}
</div>
);
};
export default TemplateList;
这是我的模板卡:
type Props = {
title: string;
description: string;
img: string;
classNameToAdd?: string;
classNameOnSelected?: string;
};
const TemplateCard = ({ title, description, img, classNameToAdd, classNameOnSelected }: Props) => {
const { aspectRatio, vmin } = useWindowResponsiveValues();
let className = `${styles.card} ${classNameToAdd}`;
const [selected, setSelected] = useState(false);
const handleClick = () => {
setSelected(!selected);
};
if (selected) {
className += `${styles.card} ${classNameToAdd} ${classNameOnSelected}`;
}
return (
<div style={card} className={className} onClick={handleClick}>
<img style={imageSize} src={img}></img>
<div style={cardTitle}>
{title}
{selected ? <BlueCheckIcon style={blueCheck} className={styles.blueCheck} /> : null}
</div>
<div style={descriptionCard}>{description}</div>
</div>
);
};
TemplateCard.defaultProps = {
classNameOnSelected: styles.selected,
};
export default TemplateCard;
这是现在的样子。
至少有 3 种方法可以实现您的要求:
选项 1
将 Button 组件放入
<TemplateList>
组件添加一个
useState
绑定到<TemplateList>
组件以保存数量 已选择的卡片添加两个新道具
onSelectCard
和onDeselectCard
到<TemplateCard>
到 increment/decrement 由1
为每个 selected/deselected 项在
<TemplateList
组件内实现回调函数(代码如下)需要时在
<TemplateCard>
中调用onSelectCard
(代码如下)
模板列表组件
const TemplateList = ({ templates }: Props) => {
const [noOfSelectedCards, setNoOfSelectedCards] = useState(0);
handleSelect = () => setNoOfSelectedCards(noOfSelectedCards + 1);
handleDeselect = () => setNoOfSelectedCards(noOfSelectedCards - 1);
return (
<div classNae="template-list-container">
<div className={styles.scrollContainer}>
{templates.map((item) => (
<TemplateCard
title={item.title}
description={item.description}
img={item.imgURL}
classNameToAdd={styles.cardContainer}
key={item.id}
onSelectCard={handleSelect}
onDeselectCard={handleDeselect}
/>
))}
</div>
<MenuButton style={actionButton} onClick={onOnboardingComplete} className={noOfSelectedCards === 2 ? 'active' : ''}>
Select at least 2 options
</MenuButton>
</div>
);
};
TemplateCard组件
const TemplateCard = ({ ..., onSelectCard, onDeselectCard }: Props) => {
...
const [selected, setSelected] = useState(false);
const handleClick = () => {
if(selected) {
onDeselectCard();
} else {
onSelectCard();
}
setSelected(!selected);
};
...
};
现在,您将在您的状态 noOfSelectedCards
(<TemplateList>
组件)中拥有当前所选卡片的数量,因此您可以有条件地呈现任何 className
您想要的按钮或用它做点别的事。
选项 2
使用React Context在组件之间共享状态
在这种情况下使用 React Context 是可以的,但是如果您的要求包含应用程序中组件之间 handling/sharing 状态的其他类似情况,我建议您看一下第三个选项。
选项 3
使用 Redux 之类的状态管理来处理组件之间的 global/shared 状态。
对于跨应用程序共享状态非常普遍且重要的项目,这可能是最佳选择。您需要一些时间来了解有关 Redux 的概念,但在您了解之后,我向您保证您会喜欢使用它。