问题
I have a component using a react hook to change the text of a styled collapse/accordion panel whenever a user clicks to open it. The problem I'm having is that this logic is effecting the text for all 3 collapse panels at the same time instead of just the panel being opened. I've included a link to a code sandbox to highlight the behavior and I've included the code below
Code Sandbox
https://codesandbox.io/s/q-56761334-style-collapse-extra-bdcbz
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Col, Row, Collapse } from "antd";
import styled from "styled-components";
import "antd/dist/antd.css";
const Flexbox = styled.div`
font-family: sans-serif;
flex-direction: column;
display: flex;
justify-content: center;
border: solid 1px palevioletred;
padding: 10%;
margin: 10%;
`;
const StyledCollapse = styled(Collapse)`
&&& {
border: none;
border-radius: 0px;
background-color: #f7f7f7;
box-shadow: none;
}
`;
const StyledH1 = styled.h1`
font-weight: 700;
`;
function FromValidate() {
const [disabled, setDisabled] = useState(true);
return (
<Flexbox>
<Row>
<Col span={12}>
<StyledCollapse onChange={() => setDisabled(prev => !prev)}>
<Collapse.Panel
header="DROPDOWN EXAMPLE"
key="1"
showArrow={false}
bordered={false}
extra={<p>{disabled ? "SHOW" : "HIDE"}</p>}
>
<div>
<StyledH1>Placeholder</StyledH1>
</div>
</Collapse.Panel>
</StyledCollapse>
<StyledCollapse onChange={() => setDisabled(prev => !prev)}>
<Collapse.Panel
header="DROPDOWN EXAMPLE"
key="1"
showArrow={false}
bordered={false}
extra={<p>{disabled ? "SHOW" : "HIDE"}</p>}
>
<div>
<StyledH1>Placeholder</StyledH1>
</div>
</Collapse.Panel>
</StyledCollapse>
</Col>
</Row>
</Flexbox>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<FromValidate />, rootElement);
回答1:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Col, Row, Collapse } from "antd";
import styled from "styled-components";
import "antd/dist/antd.css";
const Flexbox = styled.div`
font-family: sans-serif;
flex-direction: column;
display: flex;
justify-content: center;
border: solid 1px palevioletred;
padding: 10%;
margin: 10%;
`;
const StyledCollapse = styled(Collapse)`
&&& {
border: none;
border-radius: 0px;
background-color: #f7f7f7;
box-shadow: none;
}
`;
const StyledH1 = styled.h1`
font-weight: 700;
`;
function FromValidate() {
const [disabled, setDisabled] = useState(true);
const [disabled1, setDisabled1] = useState(true);
return (
<Flexbox>
<Row>
<Col span={12}>
<StyledCollapse onChange={() => setDisabled(prev => !prev)}>
<Collapse.Panel
header="DROPDOWN EXAMPLE"
key="1"
showArrow={false}
bordered={false}
extra={<p>{disabled ? "SHOW" : "HIDE"}</p>}
>
<div>
<StyledH1>Placeholder</StyledH1>
</div>
</Collapse.Panel>
</StyledCollapse>
<StyledCollapse onChange={() => setDisabled1(prev => !prev)}>
<Collapse.Panel
header="DROPDOWN EXAMPLE"
key="1"
showArrow={false}
bordered={false}
extra={<p>{disabled1 ? "SHOW" : "HIDE"}</p>}
>
<div>
<StyledH1>Placeholder</StyledH1>
</div>
</Collapse.Panel>
</StyledCollapse>
</Col>
</Row>
</Flexbox>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<FromValidate />, rootElement);
or u can create a custom component like this:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Col, Row, Collapse } from "antd";
import styled from "styled-components";
import "antd/dist/antd.css";
const Flexbox = styled.div`
font-family: sans-serif;
flex-direction: column;
display: flex;
justify-content: center;
border: solid 1px palevioletred;
padding: 10%;
margin: 10%;
`;
const StyledCollapse = styled(Collapse)`
&&& {
border: none;
border-radius: 0px;
background-color: #f7f7f7;
box-shadow: none;
}
`;
const StyledH1 = styled.h1`
font-weight: 700;
`;
function FromValidate() {
return (
<Flexbox>
<Row>
<Col span={12}>
<Customcollapse header="example1" />
<Customcollapse header="example2" />
</Col>
</Row>
</Flexbox>
);
}
const Customcollapse = props => {
const [disabled, setDisabled] = useState(true);
return (
<StyledCollapse onChange={() => setDisabled(prev => !prev)}>
<Collapse.Panel
header={props.header}
key="1"
showArrow={false}
bordered={false}
extra={<p>{disabled ? "SHOW" : "HIDE"}</p>}
>
<div>
<StyledH1>Placeholder</StyledH1>
</div>
</Collapse.Panel>
</StyledCollapse>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<FromValidate />, rootElement);
回答2:
It is because you use the same disabled
variable in all elements.
you need separate disabled
(e.x. disabledA
, disabledB
) variable for each element.
来源:https://stackoverflow.com/questions/56774261/react-react-hooks-onchange-function-to-change-text-is-changing-for-all-3-elemen