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

前提是你 提交于 2019-12-23 15:44:17

问题


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



回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!