Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React/React Hooks: onChange function to change text is changing for all 3 elements simultaneously instead of just one

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);

like image 586
Josh Avatar asked Nov 19 '25 23:11

Josh


2 Answers

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);
both collapse have same state that why they are changing at same u need to give each one a state like this!

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);
like image 103
adel Avatar answered Nov 22 '25 15:11

adel


It is because you use the same disabled variable in all elements. you need separate disabled(e.x. disabledA, disabledB) variable for each element.

like image 20
Ostoja Avatar answered Nov 22 '25 16:11

Ostoja



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!