【问题标题】:React-bootstrap - Invalid hook call - ButtonDropdownReact-bootstrap - 无效的挂钩调用 - ButtonDropdown
【发布时间】:2020-10-19 01:28:00
【问题描述】:

我是 React 和 JS 的新手,我正在尝试为我的 CRUD SpringBoot 应用程序实现一个 React 前端。我正在尝试将 ButtonDropdown 添加到我的一个页面。

代码如下:

通用buttondrop.js

import React, { Component, useState } from 'react';
import { ButtonDropdown, DropdownMenu, DropdownItem, DropdownToggle } from 'reactstrap';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';

const Bdrop = (props) => {
  const [dropdownOpen, setOpen] = useState(false);

  const toggle = () => setOpen(!dropdownOpen);

  return (
    <ButtonDropdown isOpen={dropdownOpen} toggle={toggle}>
      <DropdownToggle caret>
        Button Dropdown
      </DropdownToggle>
      <DropdownMenu>
            <Dropdown.Item href="#/action-1">Action</Dropdown.Item>
            <Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
            <Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
      </DropdownMenu>
    </ButtonDropdown>
  );
}

App.js

import React, { Component } from 'react';
import './App.css';
import Home from './Home';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import CustomerList from './CustomerList';
import EmployeeList from './EmployeeList';
import CustomerEdit from './CustomerEdit';
import EmployeeEdit from './EmployeeEdit';
import SessionList from './SessionList';
import Bdrop from './buttondrop';


class App extends Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route path='/' exact={true} component={Home}/>
          <Route path='/customers' exact={true} component={CustomerList}/>
          <Route path='/customer/:id' component={CustomerEdit}/>
          <Route path='/employees' exact={true} component={EmployeeList}/>
          <Route path='/employee/:id' component={EmployeeEdit}/>
          <Route path='/sessions' exact={true} component={SessionList}/>
          <Route path='/buttondrop' component={() => <Bdrop /> }/>


        </Switch>
      </Router>
    )
  }
}

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.min.css';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);


serviceWorker.unregister();

CustomerList.js

import React, { Component, useState } from 'react';
import { Button, ButtonGroup, Container, Table} from 'reactstrap';
import { ButtonDropdown, DropdownMenu, DropdownItem, DropdownToggle } from 'reactstrap';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton'
import AppNavbar from './AppNavbar';
import { Link } from 'react-router-dom';
import Bdrop from './buttondrop';


class CustomerList extends Component {

    constructor(props) {
        super(props);
        this.state = {
          customers: [],
          isLoading: true

        };
        this.remove = this.remove.bind(this);
    }

    componentDidMount() {
        this.setState({isLoading: true});

        fetch('/api/customers')
            .then(response => response.json())
            .then(data => this.setState({customers: data, isLoading: false}))

    }

    async remove(id) {
        await fetch(`/api/customer/${id}`, {
          method: 'DELETE',
          headers: {
            'Accept': 'application/json',
            'Content-type': 'application/json'
          }
        }).then(() => {
          let updatedCustomers = [...this.state.customers].filter(i => i.customer_id !== id);
          this.setState({customers: updatedCustomers});
        });
    }

    render() {

      const {customers, isLoading} = this.state;


      if(isLoading) {
        return<p> Loading...</p>;
      }


      const customerList = customers.map(customer => {
      return <tr key={customer.customer_id}>
        <td style={{whiteSpace: 'nowrap'}}>{customer.customer_id}</td>
        <td>{customer.first_name}</td>
        <td>{customer.last_name}</td>
        <td>{customer.phone_number}</td>

        <td>
          <ButtonGroup>
            <Button size="sm" color="primary" tag={Link} to={"/customer/" + customer.customer_id}>Edit</Button>
            <Button size="sm" color="danger" onClick={() => this.remove(customer.customer_id)}>Delete</Button>
          </ButtonGroup>
        </td>
      </tr>
    });



    return (
      <div>
        <AppNavbar/>
        <Container fluid>
          <div className="float-right">
            <Button color="success" tag={Link} to="customer/new">Add Customer</Button>
          </div>
          <h3>Customers</h3>
      {   /* <Bdrop/> */ }

          <Table className="mt-4">
            <thead>
            <tr>
              <th width="15%">Customer ID</th>
              <th width="20%">First Name</th>
              <th width="20%">Last Name</th>
              <th width="20%">Phone Number</th>
              <th width="10%">Actions</th>
            </tr>
            </thead>
            <tbody>
            {customerList}
            </tbody>
          </Table>
        </Container>
      </div>
    );


}
}
export default CustomerList;

Home.js

import React, { Component } from 'react';
import './App.css';
import AppNavbar from './AppNavbar';
import { Link } from 'react-router-dom';
import { Button, Container } from 'reactstrap';
import { ButtonDropdown, DropdownMenu, DropdownItem, DropdownToggle } from 'reactstrap';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton'

class Home extends Component {
  render() {
    return (
      <div>
        <AppNavbar/>
        <Container fluid>
           <h3>Welcome to GMusicAcademy Manager</h3>

        </Container>
        <Container fluid>
          <Button color="link"><Link to="/customers">Manage GMusicAcademy Customers</Link></Button>
          <Button color="link"><Link to="/employees">Manage GMusicAcademy Employees</Link></Button>
          <Button color="link"><Link to="/sessions">Manage GMusicAcademy Sessions</Link></Button>
          <Button color="link"><Link to="/buttondrop">Manage GMusicAcademy ButtonDropDown</Link></Button>

        </Container>
      </div>
    );
  }
}

export default Home;

目标是在此处将Bdrop添加到CustomerList(代码中已注释掉):

<h3>Customers</h3>
     <Bdrop/> 
     <Table className="mt-4"> 

这会导致“无效的挂钩调用错误”。我有相同版本的 react 和 react-dom,所以不是那样的。

为了帮助解决这个问题,我决定尝试创建一个到 Bdrop 的路由,看看我是否可以让它工作,但这也没有奏效。我尝试了不同的方法,例如:

&lt;Route path='/buttondrop' component={() =&gt; &lt;Bdrop /&gt; }/&gt;

或者

&lt;Route path='/buttondrop' render={() =&gt; &lt;Bdrop /&gt; }/&gt;

这也会导致“无效的挂钩错误”。

我试过了

&lt;Route path='/buttondrop'&gt; &lt;Bdrop /&gt; &lt;/Route&gt;

这会导致“React.Children.only 预期会收到单个 React 元素子”错误。

请帮忙!理想情况下,我想了解这两个问题。

【问题讨论】:

    标签: javascript reactjs react-hooks react-bootstrap reactstrap


    【解决方案1】:

    这是一个 sandbox link 到一个带有工作 &lt;Bdrop /&gt; 组件的版本。

    在不知道您正在使用的 Bootstrap、react-bootstrap 和 reactstrap 的版本的情况下,很难说这是否是导致您出现问题的原因。

    【讨论】:

    • 呃问题是我的依赖项的版本。我更新了 react-router-dom 以匹配 react-router,并且我更新了 reactstrap 并且它起作用了。感谢您的回复!
    猜你喜欢
    • 1970-01-01
    • 2020-02-08
    • 2021-04-20
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2020-06-27
    相关资源
    最近更新 更多