Accordion自定义切换(react bootstrap)和componentDidUpdate()兼容性问题



我现在正在使用自定义切换实现react bootstrap Accordion,参考如下。

https://react-bootstrap.github.io/components/accordion/

但是,如果您的代码中有componentDidUpdate((,Accordion就不起作用。

  1. 单击Accordion的自定义切换
  2. Accordion崩溃扩大
  3. 但是componentDidUpdate((或componentDidMount((被踢出,它会更新屏幕。他们使用fetch从服务器中提取数据。这似乎是个问题
  4. 刚刚扩大的Accordion Collapse立即折叠
  5. 所以你不能扩大协议

任何人都可以为我提供任何解决方案?

整个代码如下。

import React from 'react';
import {Accordion, Card, useAccordionToggle, ListGroup} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
class EMP extends React.Component {
constructor(props) {
super(props);
this.state = {employees: []}
}

componentDidMount() {
fetch('/SQLite/employees')
.then(response => response.json())
.then(employees => this.setState({ employees }));
}

componentDidUpdate() {
fetch('/SQLite/employees')
.then(response => response.json())
.then(employees => this.setState({ employees }));
}

render() {
return (
<div>
<EmployeeList employees={this.state.employees} />
</div>
)
}
}
class EmployeeList extends React.Component {
constructor(props) {
super(props);
}

render() {
const CustomToggle = ({ children, eventKey }) => {
const decoratedOnClick = useAccordionToggle(
eventKey, 
(e) =>{
var item = e.target.parentNode.children[0];
if(item.innerText.includes('▶',0)){
item.innerText = item.innerText.replace('▶', '▼');
}
else{
item.innerText = item.innerText.replace('▼', '▶');
}
}
);
return (
<ListGroup.Item
onClick={decoratedOnClick}
style={{cursor: 'pointer', paddingBottom: '0', paddingTop: '0' }}
>
{children}
</ListGroup.Item>
);
}

return (
<Accordion defaultActiveKey='0'>
<Card>
<Card.Header>
<CustomToggle eventKey='0'>▶ Click me!</CustomToggle>
</Card.Header>
<Accordion.Collapse eventKey='0'>
<Card.Body>Hello! Im the body</Card.Body>
</Accordion.Collapse>
</Card>
<Card>
<Card.Header>
<CustomToggle eventKey='1'>▶ Click me!</CustomToggle>
</Card.Header>
<Accordion.Collapse eventKey='1'>
<Card.Body>Hello! Im the body</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
)
}
}
export default EMP;

我找到了问题的原因。

其中componentDidMount((和componentDidUpdate((的内容不带箭头函数(((=>fetch(((,应用程序陷入一个无限循环。

调用
  1. render((
  2. 调用this.setState((
  3. render((将再次调用

要防止这种有限循环,必须在componentDidmount((中编写箭头函数。

因此,正确完整的代码如下所示。

import React from 'react';
import {Accordion, Card, useAccordionToggle, ListGroup} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
class EMP extends React.Component {
constructor(props) {
super(props);
this.state = {employees: []}
}

componentDidMount() {
() => fetch('/SQLite/employees')
.then(response => response.json())
.then(employees => this.setState({ employees }));
}

componentDidUpdate() {
() => fetch('/SQLite/employees')
.then(response => response.json())
.then(employees => this.setState({ employees }));
}

render() {
return (
<div>
<EmployeeList employees={this.state.employees} />
</div>
)
}
}
class EmployeeList extends React.Component {
constructor(props) {
super(props);
}

render() {
const CustomToggle = ({ children, eventKey }) => {
const decoratedOnClick = useAccordionToggle(
eventKey, 
(e) =>{
var item = e.target.parentNode.children[0];
if(item.innerText.includes('▶',0)){
item.innerText = item.innerText.replace('▶', '▼');
}
else{
item.innerText = item.innerText.replace('▼', '▶');
}
}
);
return (
<ListGroup.Item
onClick={decoratedOnClick}
style={{cursor: 'pointer', paddingBottom: '0', paddingTop: '0' }}
>
{children}
</ListGroup.Item>
);
}

return (
<Accordion defaultActiveKey='0'>
<Card>
<Card.Header>
<CustomToggle eventKey='0'>▶ Click me!</CustomToggle>
</Card.Header>
<Accordion.Collapse eventKey='0'>
<Card.Body>Hello! Im the body</Card.Body>
</Accordion.Collapse>
</Card>
<Card>
<Card.Header>
<CustomToggle eventKey='1'>▶ Click me!</CustomToggle>
</Card.Header>
<Accordion.Collapse eventKey='1'>
<Card.Body>Hello! Im the body</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
)
}
}
export default EMP;

最新更新