mercredi 27 mai 2020

How to wait to render components until SearchBar onClick has been pressed?

I am new to React and want to build an website based on financial information. I have a SearchBar that autocompletes with stock tickers, and I want to not render any other components until a ticker is chosen. This is because I don't want to waste free API calls.

This is my Search Bar class and below that is my class for , sorry for the horrible coding practices, still very new to React and coding.

import React, { Component } from 'react';
import './SearchBar.css';



export class SearchBar extends Component {
    constructor(props) {
        super(props);
        this.state = {
            search: '',
            tickerList: [],
        }
    }




    fetchTickers(stockSymbol) {
        const pointer = this;
        let arr = [];
        console.log(stockSymbol);
        let url = `https://ticker-2e1ica8b9.now.sh/keyword/${stockSymbol}`;
        fetch(url) 
            .then( function(response) {
                return response.json();
            })
            .then ( function(data) {
                for (var key in data) {
                    arr.push(data[key]['symbol'] + ", "+ data[key]['name'])
                };

                pointer.setState({
                    tickerList: arr
                })
            }

            )
    }


    textChange = (e) => {
        const value = e.target.value;
        let arr = [];
        if (value.length > 0) {
            const regex = new RegExp(`^${value}`, 'i');
            this.fetchTickers(value);
            arr = this.state.tickerList.sort().filter(tick => regex.test(tick));
        }
        this.setState({
            tickerList: arr,
            search: value
        });
    }

    tickerChosen(value) {
        let value1 = value.split(`,`);
        value = value1[0];

        this.setState({
            search: value,
            tickerList: []
        })


    };


    tickerSuggestions () {
        const { tickerList } = this.state;
        if (tickerList.length === 0) {
            return null;
        }
        return (
            <ul>
                {tickerList.map((ticker) => <li onClick={() => this.tickerChosen(ticker)}>{ticker}</li>)}
            </ul>
        )
    };



    render() {
        const { search } = this.state;
        return (
            <div className= 'SearchBar'>
                <input value = { search } onChange={this.textChange} type='text' />
                {this.tickerSuggestions()}
            </div>
        )
    }
}

export default SearchBar

This Component will get stock data from an API and make a chart from it. I want to not render this until a search item is selected/clicked.

import React, { Component } from 'react';
import Plot from 'react-plotly.js';


class StockChart extends Component {
    constructor(props) {
        super(props);
        this.state = {
            stockXValues: [],
            stockYValues: [],
            stockSymbol: this.props.stockSymbol

        }
    }

    componentDidMount() {
        this.fetchStock();
    }

    fetchStock() {
        const pointer = this;
        console.log(pointer);
        const API_KEY = `X`;
        let API_Call = `https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=${this.props.stockSymbol}&outputsize=compact&apikey=${API_KEY}`;
        let StockXValuesFunc = [];
        let StockYValuesFunc = [];



        fetch(API_Call)
            .then(
                function(response) {
                    return response.json();
                }
            )
            .then(
                function(data) {
                    console.log(data);

                    for (var key in data['Time Series (Daily)']) {
                        StockXValuesFunc.push(key);
                        StockYValuesFunc.push(data['Time Series (Daily)']
                        [key]['4. close']);
                    }
                    pointer.setState({
                        stockXValues: StockXValuesFunc,
                        stockYValues: StockYValuesFunc
                    });


                }
            )

    }
    render() {
      return (
        <div>
            <h2>StockChart</h2>
            <form onSubmit={this.fetchStock}>

            </form>
            <Plot
                data={[
                {
                    x: this.state.stockXValues,
                    y: this.state.stockYValues,
                    type: 'scatter',
                    mode: 'lines+markers',
                    marker: {color: 'red'},
                },
                ]}
                layout={ {width: 720, height: 440, title: 'Closing Price over the last 100 days'} }
            />
        </div>
      )
  }
}

export default StockChart;



Aucun commentaire:

Enregistrer un commentaire