【问题标题】:How to access URL param to update component state in class component?如何访问 URL 参数以更新类组件中的组件状态?
【发布时间】:2021-12-30 07:37:27
【问题描述】:

我有一个调用两个 API URL 的 React 组件,现在可以进行提取。但我想使用类似localhost://site/coins/[handle] 的结构的URL 句柄作为获取不同数据点的参数。

我计划的使用方式是:

import { useRouter } from 'next/router'
const router = useRouter()

但我收到一个错误:

错误:无效的挂钩调用。钩子只能在体内调用 一个函数组件。

这是我的组件:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      coin: 'bitcoin',
      CoinData: [],
      historicData: [],
      DataisLoaded: false,
    };
  }

  componentDidMount() {
    fetch(
      'https://api.coingecko.com/api/v3/simple/price?ids=' +
        this.state.coin +
        '&vs_currencies=usd&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true&include_last_updated_at=true'
    )
      .then((res) => res.json())
      .then((json) => {
        this.setState({
          CoinData: json,
          DataisLoaded: true,
        });
      });
    fetch(
      'https://api.coingecko.com/api/v3/coins/' +
        this.state.coin +
        '/market_chart?vs_currency=usd&days=3'
    )
      .then((res) => res.json())
      .then((json) => {
        this.setState({
          historicData: json,
        });
      });
  }

  render() {
    const { DataisLoaded, CoinData, historicData, coin } = this.state;

    // console.log(processedData);
    if (!DataisLoaded) return <Skeleton />;

    return (
      <Dashboard>
        <DashboardHeader />
        <DashboardSidebar />
        <Main>
          <TopContainer>
            <div className='topContent'>
              <div role='presentation'>
                <Breadcrumbs aria-label='breadcrumb'>
                  <Link
                    underline='hover'
                    href='/'
                    fontSize='small'
                    fontFamily='Titillium Web'
                    color='#898181'
                  >
                    DefiPlatform
                  </Link>
                  <Link
                    underline='hover'
                    color='#898181'
                    href='/coins/'
                    fontSize='small'
                  >
                    Coins
                  </Link>
                  {/* <Typography color="#fff" fontSize="12px">{router.query.handle}</Typography> */}
                </Breadcrumbs>
              </div>
              <div className='coinMain'>
                <h1>
                  bitcoin
                  <Chip
                    label='BTC'
                    variant='outlined'
                    style={{ color: 'white', borderColor: '#251B55' }}
                  />
                </h1>
                <div>
                  <Chip
                    icon={<LinkIcon style={{ color: '#CECECE' }} />}
                    size='small'
                    label='Bitcoin.org'
                    style={{
                      color: '#CECECE',
                      marginTop: '5px',
                      marginRight: '5px',
                      backgroundColor: '#241E4E',
                    }}
                  />
                  <Chip
                    icon={<ArticleOutlinedIcon style={{ color: '#CECECE' }} />}
                    size='small'
                    label='Whitepaper'
                    style={{
                      color: '#CECECE',
                      marginTop: '5px',
                      marginRight: '5px',
                      backgroundColor: '#241E4E',
                    }}
                  />
                </div>
              </div>
            </div>
            <div className='coinPrice'>
              <div>
                <span className='coin_label'>bitcoin Price (BTC)</span>
                <h2>
                  {CoinData[this.state.coin].usd.toLocaleString('en-US', {
                    maximumFractionDigits: 2,
                  })}{' '}
                  <Ticker Value='1.68%' Variant='BG' />
                </h2>
              </div>
              <div className='coinComparison'>
                <div className='compareData'>12.47 ETH</div>
                <Ticker Value='2%' Variant='outline' />
              </div>
            </div>
          </TopContainer>

          <MainCards>
            <Card>
              <h6>Bitcoin to USD Chart</h6>
              {this.state.coin}
              {JSON.stringify(CoinData[this.state.coin])}
              {JSON.stringify(historicData.prices)}
              {}
            </Card>
            <Card>
              <h6>BTC Price Statistics</h6>
            </Card>
          </MainCards>
        </Main>
      </Dashboard>
    );
  }
}

export default App;

【问题讨论】:

  • 你不能在 React Class 组件中使用钩子

标签: javascript reactjs next.js fetch-api


【解决方案1】:

正如错误中提到的,React Hooks 只能在函数组件内部调用。你使用的是类组件,所以不能调用useRouter

要访问类组件中的router 实例,您必须使用withRouter HOC。然后您可以从this.props.router 访问router

import { withRouter } from 'next/router'

class App extends React.Component {
    // Your `constructor` code here

    componentDidMount() {
        console.log(this.props.router); // Logs the `router` object
        // Remaining code here
    }

    // Your `render` code here
}

export default withRouter(App);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-11
    • 2021-08-02
    • 1970-01-01
    • 2021-05-13
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多