Reactjs 如何用一个函数控制多个组件的状态
我有一个简单的应用程序,包括3个相同的按钮,当我点击按钮时,onClick事件应该会触发以显示一个Reactjs 如何用一个函数控制多个组件的状态,reactjs,typescript,Reactjs,Typescript,我有一个简单的应用程序,包括3个相同的按钮,当我点击按钮时,onClick事件应该会触发以显示一个span。现在,我已经使用一个one state来控制span显示与否,一旦我点击了所有span显示按钮中的任何一个。如何实现代码,因此当我单击按钮时,仅显示相应的span import "./styles.css"; import React, { useState } from "react"; const Popup = (props) => {
span
。现在,我已经使用一个one state
来控制span
显示与否,一旦我点击了所有span
显示按钮中的任何一个。如何实现代码,因此当我单击按钮时,仅显示相应的span
import "./styles.css";
import React, { useState } from "react";
const Popup = (props) => {
return <span {...props}>xxx</span>;
};
export default function App() {
const [isOpen, setIsOpen] = useState(true);
const handleOnClick = () => {
setIsOpen(!isOpen);
};
return (
<div className="App">
<button onClick={handleOnClick}> Show popup1</button>
<Popup hidden={isOpen} />
<button onClick={handleOnClick}> Show popup2</button>
<Popup hidden={isOpen} />
<button onClick={handleOnClick}> Show popup3</button>
<Popup hidden={isOpen} />
</div>
);
}
导入“/styles.css”;
从“React”导入React,{useState};
常量弹出=(道具)=>{
返回xxx;
};
导出默认函数App(){
常数[isOpen,setIsOpen]=useState(真);
const handleOnClick=()=>{
setIsOpen(!isOpen);
};
返回(
显示弹出窗口1
显示弹出窗口2
显示弹出窗口3
);
}
代码沙盒:
您应该重新考虑如何使用这些组件。 由于存在重复的逻辑和接口,因此应将其分离到不同的组件
const Popup = (props) => {
return <span {...props}>xxx</span>;
};
interface Props {
buttonText: string
popupProps?: any
}
const PopupFC: React.FC<Props> = (props) => {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onClick={() => setIsOpen(!isOpen)}>{props.buttonText}</button>
<Popup hidden={isOpen} {...props.popupProps} />
</>
)
}
export default function App() {
const [isOpen, setIsOpen] = useState(true);
const handleOnClick = () => {
setIsOpen(!isOpen);
};
return (
<div className="App">
<PopupFC buttonText="Show popup1" />
<PopupFC buttonText="Show popup2" />
<PopupFC buttonText="Show popup3" />
</div>
);
}
const Popup=(道具)=>{
返回xxx;
};
界面道具{
buttonText:字符串
popupProps?:有吗
}
常量PopupFC:React.FC=(道具)=>{
常量[isOpen,setIsOpen]=useState(false);
返回(
setIsOpen(!isOpen)}>{props.buttonText}
)
}
导出默认函数App(){
常数[isOpen,setIsOpen]=useState(真);
const handleOnClick=()=>{
setIsOpen(!isOpen);
};
返回(
);
}
您应该重新考虑如何使用这些组件。
由于存在重复的逻辑和接口,因此应将其分离到不同的组件
const Popup = (props) => {
return <span {...props}>xxx</span>;
};
interface Props {
buttonText: string
popupProps?: any
}
const PopupFC: React.FC<Props> = (props) => {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onClick={() => setIsOpen(!isOpen)}>{props.buttonText}</button>
<Popup hidden={isOpen} {...props.popupProps} />
</>
)
}
export default function App() {
const [isOpen, setIsOpen] = useState(true);
const handleOnClick = () => {
setIsOpen(!isOpen);
};
return (
<div className="App">
<PopupFC buttonText="Show popup1" />
<PopupFC buttonText="Show popup2" />
<PopupFC buttonText="Show popup3" />
</div>
);
}
const Popup=(道具)=>{
返回xxx;
};
界面道具{
buttonText:字符串
popupProps?:有吗
}
常量PopupFC:React.FC=(道具)=>{
常量[isOpen,setIsOpen]=useState(false);
返回(
setIsOpen(!isOpen)}>{props.buttonText}
)
}
导出默认函数App(){
常数[isOpen,setIsOpen]=useState(真);
const handleOnClick=()=>{
setIsOpen(!isOpen);
};
返回(
);
}
如果每个弹出窗口
都需要自己的isOpen
状态,则无法使用单个布尔状态实现。
也许可以将按钮和跨度转换为单个组件,并让每个弹出窗口
组件处理自己的isOpen
:
导入“/styles.css”;
从“React”导入React,{useState};
常量弹出=(道具)=>{
常数[isOpen,setIsOpen]=useState(真);
const handleOnClick=()=>{
setIsOpen(!isOpen);
};
返回(
{props.children}
{isOpen&&xxx}
);
};
导出默认函数App(){
返回(
显示弹出窗口1
显示弹出窗口2
显示弹出窗口3
);
}
如果每个
弹出窗口
都需要自己的isOpen
状态,则无法使用单个布尔状态实现。
也许可以将按钮和跨度转换为单个组件,并让每个弹出窗口
组件处理自己的isOpen
:
导入“/styles.css”;
从“React”导入React,{useState};
常量弹出=(道具)=>{
常数[isOpen,setIsOpen]=useState(真);
const handleOnClick=()=>{
setIsOpen(!isOpen);
};
返回(
{props.children}
{isOpen&&xxx}
);
};
导出默认函数App(){
返回(
显示弹出窗口1
显示弹出窗口2
显示弹出窗口3
);
}
发生这种情况的原因很简单,因为您对所有按钮使用相同的状态“isOpen”, 单击其中任何一个按钮后,它将反映所有按钮,因为它的值相同。
您可以使用自定义钩子解决此问题,因为您可以重复此逻辑,也可以将它们分割为小组件,这仅仅是因为您对所有按钮使用相同的状态“isOpen”, 单击其中任何一个按钮后,它将反映所有按钮,因为它的值相同。
您可以使用自定义钩子解决此问题,因为您可以重复此逻辑,也可以根据您的评论将它们分成小的组件,您一次只希望打开一个弹出窗口。这在你原来的问题中不清楚,所以其他答案没有解决这个问题 现在,您只需存储一个
isOpen
值,即true
或false
。这还不够。您如何知道哪个弹出窗口处于打开状态
如果您希望一次只显示一个,您可以存储当前打开的弹出窗口的编号或名称(任何类型的唯一id)
我们将弹出窗口
设置为一个“受控组件”,它不管理自己的内部isOpen
状态,而是通过道具
接收和更新该信息
App
组件负责管理打开的弹出窗口,并将正确的道具传递给每个popup
组件。由于我们对多个弹出窗口执行相同的操作,因此我将该逻辑移到了renderpop
helper函数中
弹出窗口
interface PopupProps {
isOpen: boolean;
open: () => void;
close: () => void;
label: string;
}
const Popup = ({ isOpen, open, close, label }: PopupProps) => {
return (
<>
<button onClick={open}> Show {label}</button>
{isOpen && (
<div>
<h1>{label}</h1>
<span>xxx</span>
<button onClick={close}>Close</button>
</div>
)}
</>
);
};
export default function App() {
// store the label of the popup which is open,
// or `null` if all are closed
const [openId, setOpenId] = useState<string | null>(null);
const renderPopup = (label: string) => {
return (
<Popup
label={label}
isOpen={openId === label} // check if this popup is the one that's open
open={() => setOpenId(label)} // open by setting the `openId` to this label
close={() => setOpenId(null)} // calling `close` closes all
/>
);
};
return (
<div className="App">
{renderPopup("Popup 1")}
{renderPopup("Popup 2")}
{renderPopup("Popup 3")}
</div>
);
}
接口PopupProps{
等参:布尔;
打开:()=>无效;
关闭:()=>无效;
标签:字符串;
}
常量弹出=({isOpen,open,close,label}:PopupProps)=>{
返回(
显示{label}
{isOpen&&(
{label}
xxx
接近
)}
);
};
应用程序
interface PopupProps {
isOpen: boolean;
open: () => void;
close: () => void;
label: string;
}
const Popup = ({ isOpen, open, close, label }: PopupProps) => {
return (
<>
<button onClick={open}> Show {label}</button>
{isOpen && (
<div>
<h1>{label}</h1>
<span>xxx</span>
<button onClick={close}>Close</button>
</div>
)}
</>
);
};
export default function App() {
// store the label of the popup which is open,
// or `null` if all are closed
const [openId, setOpenId] = useState<string | null>(null);
const renderPopup = (label: string) => {
return (
<Popup
label={label}
isOpen={openId === label} // check if this popup is the one that's open
open={() => setOpenId(label)} // open by setting the `openId` to this label
close={() => setOpenId(null)} // calling `close` closes all
/>
);
};
return (
<div className="App">
{renderPopup("Popup 1")}
{renderPopup("Popup 2")}
{renderPopup("Popup 3")}
</div>
);
}
导出默认函数App(){
//存储打开的弹出窗口的标签,
//如果全部关闭,则为空
const[openId,setOpenId]=useState(null);
常量renderPopup=(标签:string)=>{
返回(
根据您的评论,您一次只希望打开一个弹出窗口。这在您的原始问题中不清楚,因此其他答案无法解决此问题
现在您只存储一个isOpen
值,即true
或false
。这是不够的信息。您如何知道哪个弹出窗口