如何通过单击组件中的图标来滚动和展开手风琴?
How to scroll and expand an Accordion by onClick on an icon from a component?
我有一个组件 MainContent
及其子组件 AddMock
。 MainContent
中有一个 table,它显示了一些项目列表。它对每一行都有一定的动作,比如查看和编辑,这些动作是由图标通过语义-UI 反应呈现的。通过单击每个图标,我需要向上滚动并展开手风琴。手风琴在 AddMock
.
// AddMock.js
const AddMock = () => {
return (
<div className="row">
<Accordion style={{ paddingLeft: "32px" }}>
<Card className="collapseStyle">
<Card.Header>
<Accordion.Toggle as={Button} variant="link" eventKey="0">
Add Mock
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
<Container className="mockbody">
<Header as="h3">Hierarchy</Header>
<TabContent />
</Container>
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
</div>
);
};
下面是MainContent.js
const MainContent = () => {
return (
<div>
<AddMock />
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
<div className="card">
<div className="card-header card-header-info">
<h4 className="card-title ">MOCK</h4>
</div>
<div className="card-body">
<form>
{loading ? (
<div className="table-responsive">
<table className="table">
<thead>
<tr>
<th>AppName</th>
<th>Parent_App</th>
<th>Created_Date</th>
<th>Req_Path</th>
<th>Resp_Code</th>
<th>Resp_Content_Type</th>
<th>Resp_Delay</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{data.map((routes, index) => {
return routes.map(contents, index);
})}
</tbody>
</table>
</div>
) : (
<Spinner
animation="border"
style={{ marginLeft: "620px" }}
/>
)}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
是否可以使用 window.scrollTo() 或任何其他更好的方式在 React 中实现它?
使用参考
首先,我们可以有一个状态来保持活动 Accordion
的 eventKey
const [activeKey, setActiveKey] = useState("");
之后,我们为 React-Bootstrap 手风琴组件使用 ref
。稍后我们需要使用 Forwarded Refs 至少将 ref 分配给 Accordion 组件的最顶层 DOM 元素,以便我们可以滚动到它。
至于图标,看看它的 onClick
事件,这只是将 activeKey
设置为 "0"
,它映射到 Accordion.Collapse
组件的 eventKey
。这将作为其“扩张”的触发点。
// we are going to need a ref to the Accordion element go get its position/use the scrollIntoView function
const accordElem = useRef(null);
const handleClickEdit = () => {
setActiveKey("0"); // "0" here is as defined in your Accordion.Collapse eventKey
accordElem.current.scrollIntoView({
behavior: "smooth",
block: "end",
inline: "nearest"
}); // initiate scroll to the "AddMock" Accordion component
};
return (
<div>
<AddMock
activeKey={activeKey}
setActiveKey={setActiveKey}
ref={accordElem}
/>
...
<Icon
name="pencil"
size="huge"
style={{ cursor: "pointer" }}
onClick={() => handleClickEdit("0")}
/>
对于滚动我们可以使用https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. In addition, there are of course other alternatives such as scrollTo
最后,这是我们的 Accordion 组件在转发引用和利用从父状态获取的 activeKey
属性时的样子:
const AddMock = React.forwardRef((props, ref) => {
// optional re-toggling of expanded accordion
function handleClickToggle(eventKey) {
if (eventKey === props.activeKey) {
props.setActiveKey("");
} else {
props.setActiveKey(eventKey);
}
}
return (
<div className="row" ref={ref}>
<Accordion style={{ paddingLeft: "32px" }} activeKey={props.activeKey}>
<Card className="collapseStyle">
<Card.Header>
<Accordion.Toggle
as={Button}
variant="link"
eventKey="0"
onClick={() => handleClickToggle("0")}
>
Add Mock
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
...
代码沙盒:https://codesandbox.io/s/react-semantic-ui-react-bootstrap-3ndyl?file=/src/App.js:2444-3230
我有一个组件 MainContent
及其子组件 AddMock
。 MainContent
中有一个 table,它显示了一些项目列表。它对每一行都有一定的动作,比如查看和编辑,这些动作是由图标通过语义-UI 反应呈现的。通过单击每个图标,我需要向上滚动并展开手风琴。手风琴在 AddMock
.
// AddMock.js
const AddMock = () => {
return (
<div className="row">
<Accordion style={{ paddingLeft: "32px" }}>
<Card className="collapseStyle">
<Card.Header>
<Accordion.Toggle as={Button} variant="link" eventKey="0">
Add Mock
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
<Container className="mockbody">
<Header as="h3">Hierarchy</Header>
<TabContent />
</Container>
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
</div>
);
};
下面是MainContent.js
const MainContent = () => {
return (
<div>
<AddMock />
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
<div className="card">
<div className="card-header card-header-info">
<h4 className="card-title ">MOCK</h4>
</div>
<div className="card-body">
<form>
{loading ? (
<div className="table-responsive">
<table className="table">
<thead>
<tr>
<th>AppName</th>
<th>Parent_App</th>
<th>Created_Date</th>
<th>Req_Path</th>
<th>Resp_Code</th>
<th>Resp_Content_Type</th>
<th>Resp_Delay</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{data.map((routes, index) => {
return routes.map(contents, index);
})}
</tbody>
</table>
</div>
) : (
<Spinner
animation="border"
style={{ marginLeft: "620px" }}
/>
)}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
是否可以使用 window.scrollTo() 或任何其他更好的方式在 React 中实现它?
使用参考
首先,我们可以有一个状态来保持活动 Accordion
的eventKey
const [activeKey, setActiveKey] = useState("");
之后,我们为 React-Bootstrap 手风琴组件使用 ref
。稍后我们需要使用 Forwarded Refs 至少将 ref 分配给 Accordion 组件的最顶层 DOM 元素,以便我们可以滚动到它。
至于图标,看看它的 onClick
事件,这只是将 activeKey
设置为 "0"
,它映射到 Accordion.Collapse
组件的 eventKey
。这将作为其“扩张”的触发点。
// we are going to need a ref to the Accordion element go get its position/use the scrollIntoView function
const accordElem = useRef(null);
const handleClickEdit = () => {
setActiveKey("0"); // "0" here is as defined in your Accordion.Collapse eventKey
accordElem.current.scrollIntoView({
behavior: "smooth",
block: "end",
inline: "nearest"
}); // initiate scroll to the "AddMock" Accordion component
};
return (
<div>
<AddMock
activeKey={activeKey}
setActiveKey={setActiveKey}
ref={accordElem}
/>
...
<Icon
name="pencil"
size="huge"
style={{ cursor: "pointer" }}
onClick={() => handleClickEdit("0")}
/>
对于滚动我们可以使用https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. In addition, there are of course other alternatives such as scrollTo
最后,这是我们的 Accordion 组件在转发引用和利用从父状态获取的 activeKey
属性时的样子:
const AddMock = React.forwardRef((props, ref) => {
// optional re-toggling of expanded accordion
function handleClickToggle(eventKey) {
if (eventKey === props.activeKey) {
props.setActiveKey("");
} else {
props.setActiveKey(eventKey);
}
}
return (
<div className="row" ref={ref}>
<Accordion style={{ paddingLeft: "32px" }} activeKey={props.activeKey}>
<Card className="collapseStyle">
<Card.Header>
<Accordion.Toggle
as={Button}
variant="link"
eventKey="0"
onClick={() => handleClickToggle("0")}
>
Add Mock
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
...
代码沙盒:https://codesandbox.io/s/react-semantic-ui-react-bootstrap-3ndyl?file=/src/App.js:2444-3230