Отправка данных API в Gatsby для использования в Chart. js - PullRequest
1 голос
/ 20 июня 2020

Я пытаюсь отправить вызываемые данные API из моего индекса. js в мои ChartData. js. index. js - это страница, а ChartData. js - это компонент в Gatsby, поэтому для начала я не мог понять, работает ли функция Gatsby Link to = "" только с одной страницы на другую или может ли она отправлять данные со страницы на компонент.

Проблема в том, что я пытаюсь получить доступ к отправленным данным из индекса. js в ChartData. js в строке {props.location.state.companyName} Я получаю сообщение об ошибке: TypeError: props.location is undefined

Я планирую заменить labels: ['x', 'y'] на что-то вроде labels: [{props.location.state.companyName}, {props.location.state.symbol} et c. Я не уверен, что это правильный синтаксис.

Более подробное объяснение здесь: https://www.youtube.com/watch?v=No9cqzqlKS0&feature=youtu.be

index. js:

import React from "react"
import { Link } from "gatsby"
import axios from "axios"
import "../css/style.css"
import Layout from "../components/layout"
import { symbol } from "prop-types"
import ChartData from "../components/ChartData"

export default class index extends React.Component {
  state = {
      companyName: "",
      previousClose: "",
      marketCap: "",
      change: "",
      symbol: "",
      topStocks: [],
      Yearweekhigh: "",
      Yearweeklow: "",
      avgTotalVolume: "",
      peRatio: ""
      

  }


  componentDidMount() {
    const API_KEY = '*******************';
    axios.get(`https://cloud.iexapis.com/stable/stock/market/previous?token=${API_KEY}`)
      .then(res => {
        
        console.log(res)

        const topStocks = res.slice(1);
        this.setState({ topStocks })

      })
  }
  

  clickHandler = (event) => {
          if (event.keyCode === 13) {
          const query = event.target.value;
          const API_KEY = '*******************';
      axios.get(`https://cloud.iexapis.com/stable/stock/${query}/quote?token=${API_KEY}`)
          .then(res => {
              const companyName = res.data['companyName'];
              this.setState({ companyName })

              const previousClose = res.data['previousClose'];
              this.setState({ previousClose })

              const marketCap = res.data['marketCap'];
              this.setState({ marketCap })

              const change = res.data['change'];
              this.setState({ change })

              const symbol = res.data['symbol'];
              this.setState({ symbol })

              const Yearweekhigh = res.data['week52High'];
              this.setState({ Yearweekhigh })

              const Yearweeklow = res.data['week52Low'];
              this.setState({ Yearweeklow })

              const avgTotalVolume = res.data['avgTotalVolume'];
              this.setState({ avgTotalVolume })

              const peRatio = res.data['peRatio'];
              this.setState({ peRatio }) 


          })
      }
  }



  render() {
      return (
          <Layout>
              <div class = "main-div">
                  <input type="search" class="main-search" onKeyDown={event => this.clickHandler(event)}/>
                  <table>
                    <tr>
                      <th>Ticker-Symbol</th>
                      <th>Market Cap</th>
                      <th>Previous Close</th>
                    </tr>
                    <tr>
                    <td>
                      <Link to='/details/' state={{

                        setState: this.state.symbol, 
                        companyName: this.state.companyName, 
                        previousClose: this.state.previousClose,
                        marketCap: this.state.marketCap,
                        change: this.state.change,
                        Yearweekhigh: this.state.Yearweekhigh,
                        Yearweeklow: this.state.Yearweeklow,
                        avgTotalVolume: this.state.avgTotalVolume,
                        peRatio: this.state.peRatio

                        }}>
                          {this.state.symbol}</Link>


                          <Link to='/ChartData/' state={{

                          setState: this.state.symbol, 
                          companyName: this.state.companyName, 
                          previousClose: this.state.previousClose,
                          marketCap: this.state.marketCap,
                          change: this.state.change,
                          Yearweekhigh: this.state.Yearweekhigh,
                          Yearweeklow: this.state.Yearweeklow,
                          avgTotalVolume: this.state.avgTotalVolume,
                          peRatio: this.state.peRatio

                          }}></Link>
                        </td>
                      <td>{this.state.marketCap}</td>
                      <td>{this.state.previousClose}</td>
                    </tr>
                  </table>
              </div>
              <div>
                {
                  this.state.topStocks.length && this.state.topStocks.map(stock => (
                  <h1>{stock.symbol}</h1>
                  ))
                }
              </div>
              <ChartData />
          </Layout>
      )
  }
}

подробности. js

//import { Link } from "gatsby"
import axios from 'axios';
import React, { useEffect, useState } from 'react';
import Layout from '../components/layout';
import "../css/style.css"

const Details = props => {
  const [yourState, setYourState] = useState('');
  useEffect(() => {

  }, []);

  return  <Layout>
    <div>
    <h1 class="details-company-name">{props.location.state.companyName}</h1>
    <div class = "details-div">
      <div class="details-div-1">
        <p>Open {} </p>
        <p>High {} </p>
        <p>Low {} </p>
        <p>52 WK HIGH <h2>{props.location.state.Yearweekhigh}</h2> </p>
        <p>52 WK LOW <h2>{props.location.state.Yearweeklow}</h2> </p>
      </div>
      <div class="details-div-2">
        <p>VOLUME</p>
        <p>AVG VOL <h2>{props.location.state.avgTotalVolume}</h2> </p>
        <p>MKT CAP <h2>{props.location.state.marketCap}</h2></p>
        <p>P/E RATIO <h2>{props.location.state.peRatio}</h2></p>
        <p>DIV/YIELD</p>
      </div>
    </div>
    </div>
      </Layout>;
    };

export default Details;

ChartData. js


import React, {useState, useEffect } from "react";
import { Line } from "react-chartjs-2";


const ChartData = props => {
    const [yourState, setYourState] = useState('');

    const chart = () => {
        setYourState({
            labels: ['x', 'y'],
            datasets: [
                {
                    level: 'level of xyz',
                    data: [22, 55]
                }
            ]
        })
    }

    useEffect(() => {
        chart()

    }, [])
    return(
        <div>
            <h1>Hello</h1>
            {props.location.state.companyName}
            <div>
                <Line data={yourState}/>
            </div>
        </div>
    )
}

export default ChartData;

1 Ответ

1 голос
/ 20 июня 2020

Здесь происходит довольно много вещей, требующих разъяснения. Вы упоминаете graphql в заголовке, но в вашем коде нет graphql.

Вы используете ax ios для извлечения данных во время выполнения в методе жизненного цикла componentDidMount, а затем установив результат в состояние.

Я предполагаю, что после того, как у вас есть эти данные, все, что вам нужно сделать, это передать их компоненту диаграммы, чтобы он мог отобразить себя на странице индекса.

Рассмотрим следующий пример, который делает то же самое; Получает некоторые данные из Rick & Morty api , устанавливает результаты в состояние и передает соответствующую часть этого состояния через props непосредственно в компонент <Characters />.

Оттуда Компонент <Characters /> имеет все необходимое для рендеринга. (У него нет состояния, и его не волнует, откуда на самом деле пришли данные).

// index.js

import React from 'react';
import './App.css';
import Characters from './Characters'

const api = "https://rickandmortyapi.com/api/character/";

class IndexPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    };
  }

  componentDidMount() {
    fetch(api)
      .then(res => res.json())
      .then(
        json => {
          console.log(json)
          this.setState({
            isLoaded: true,
            data: json.results
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        error => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      );
  }

  render() {
    const { error, isLoaded, data } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <Characters data={data} />
      );
    }
  }
}

export default IndexPage;
// Characters.js

import React from 'react';

class Characters extends React.Component {
  render() {
    return (
      <ul>
        {this.props.data.map(item => (
          <li key={item.id}>
            <dl>
              <dt>Name:</dt>
              <dd>{item.name}</dd>
              <dt>Species:</dt>
              <dd>{item.species}</dd>
              <dt>Status:</dt>
              <dd>{item.status}</dd>
            </dl>
          </li>
        ))}
      </ul>
    );
  }
}

export default Characters;

Пример Codesandbox с использованием функциональных компонентов и хуков

Компонент <Link> Gatsby позволяет связывать между страницами (и выполняет некоторые другие действия, такие как предварительная выборка ресурсов и может обмениваться данными между страницами). Поскольку вы визуализируете компонент <ChartData /> на странице index, это не требуется для решения вашей проблемы.

Использование <Link> с состоянием работает, потому что details является страницей gatsby. Как <ChartData> is not a page, you can't *link* to it.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...