Introduction

Creating a stock trading web application using React.js allows us to leverage the power of a modern front-end framework to build a more dynamic and interactive application. We’ll use React components, hooks, and state management to manage user interactions and data flow.

Project Overview

Features:

  1. A search bar to find stock information by ticker symbol.
  2. Display stock details like company name, current price, daily high, and low.
  3. Buttons to simulate buying and selling shares.
  4. Displaying portfolio details.

Tools and Technologies Used

  • React.js: For building the user interface.
  • Axios: For making HTTP requests to fetch stock data.
  • CSS: For styling the page.
  • Alpha Vantage API: To fetch real-time stock data (you need an API key).

Step 1: Setting Up the React Project

First, ensure you have Node.js and npm installed. Then, create a new React project using create-react-app.

				
					npx create-react-app stock-trading-app
cd stock-trading-app
				
			

Step 2: Installing Axios

We’ll use Axios to make HTTP requests to the Alpha Vantage API. Install Axios by running:

				
					npm install axios
				
			

Step 3: Setting Up the Project Structure

Inside the src folder, create the following files:

  • components/StockSearch.js – Component for searching stocks.
  • components/StockInfo.js – Component for displaying stock details.
  • components/Portfolio.js – Component for displaying the portfolio.
  • App.js – Main component that ties everything together.
  • App.css – CSS file for styling.

Step 4: Building the Components

4.1. Creating the StockSearch Component

This component will contain the input field to enter a stock symbol and a button to search for the stock.

Create a file named StockSearch.js inside the components folder:

				
					// src/components/StockSearch.js

import React from 'react';

const StockSearch = ({ onSearch }) => {
    const [symbol, setSymbol] = React.useState('');

    const handleSearch = () => {
        if (symbol.trim() !== '') {
            onSearch(symbol.trim().toUpperCase());
        }
    };

    return (
        <div className="stock-search">
            <input
                type="text"
                value={symbol}
                onChange={(e) => setSymbol(e.target.value)}
                placeholder="Enter stock symbol (e.g., AAPL)"
            />
            <button onClick={handleSearch}>Search</button>
        </div>
    );
};

export default StockSearch;
				
			

4.2. Creating the StockInfo Component

This component will display the fetched stock information.

Create a file named StockInfo.js inside the components folder:

				
					// src/components/StockInfo.js

import React from 'react';

const StockInfo = ({ stock }) => {
    return (
        <div className="stock-info">
            {stock ? (
                <>
                    <h2>{stock.symbol}</h2>
                    <p>Price: ${stock.price}</p>
                    <p>High: ${stock.high}</p>
                    <p>Low: ${stock.low}</p>
                </>
            ) : (
                <p>No stock selected.</p>
            )}
        </div>
    );
};

export default StockInfo;
				
			

4.3. Creating the Portfolio Component

This component will display the user’s portfolio.

Create a file named Portfolio.js inside the components folder:

				
					// src/components/Portfolio.js

import React from 'react';

const Portfolio = ({ portfolio }) => {
    return (
        <div className="portfolio">
            <h2>Portfolio</h2>
            {Object.keys(portfolio).length > 0 ? (
                <ul>
                    {Object.entries(portfolio).map(([symbol, data]) => (
                        <li key={symbol}>
                            {symbol}: {data.shares} shares at ${data.price.toFixed(2)} each
                        </li>
                    ))}
                </ul>
            ) : (
                <p>No stocks bought yet.</p>
            )}
        </div>
    );
};

export default Portfolio;
				
			

Step 5: Building the Main ‘App’ Component

The App component will use the StockSearch, StockInfo, and Portfolio components. It will manage the state and handle logic for fetching data and updating the portfolio.

Update App.js to the following:

				
					// src/App.js

import React, { useState } from 'react';
import axios from 'axios';
import StockSearch from './components/StockSearch';
import StockInfo from './components/StockInfo';
import Portfolio from './components/Portfolio';
import './App.css';

const App = () => {
    const [stock, setStock] = useState(null);
    const [portfolio, setPortfolio] = useState({});

    // Function to fetch stock data
    const fetchStockData = async (symbol) => {
        const apiKey = 'your_api_key_here'; // Replace with your API key
        const apiUrl = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${symbol}&apikey=${apiKey}`;

        try {
            const response = await axios.get(apiUrl);
            const data = response.data['Global Quote'];
            if (data) {
                setStock({
                    symbol: data['01. symbol'],
                    price: parseFloat(data['05. price']),
                    high: parseFloat(data['03. high']),
                    low: parseFloat(data['04. low'])
                });
            } else {
                setStock(null);
                alert('Stock data not found.');
            }
        } catch (error) {
            console.error('Error fetching stock data:', error);
            setStock(null);
            alert('Failed to fetch stock data. Please try again.');
        }
    };

    // Function to buy stock
    const buyStock = () => {
        if (stock && stock.symbol) {
            setPortfolio((prevPortfolio) => {
                const newPortfolio = { ...prevPortfolio };
                if (newPortfolio[stock.symbol]) {
                    newPortfolio[stock.symbol].shares += 1;
                } else {
                    newPortfolio[stock.symbol] = {
                        shares: 1,
                        price: stock.price
                    };
                }
                return newPortfolio;
            });
        }
    };

    // Function to sell stock
    const sellStock = () => {
        if (stock && stock.symbol && portfolio[stock.symbol]) {
            setPortfolio((prevPortfolio) => {
                const newPortfolio = { ...prevPortfolio };
                if (newPortfolio[stock.symbol].shares > 1) {
                    newPortfolio[stock.symbol].shares -= 1;
                } else {
                    delete newPortfolio[stock.symbol];
                }
                return newPortfolio;
            });
        }
    };

    return (
        <div className="App">
            <header>
                <h1>Stock Trading App</h1>
            </header>
            <StockSearch onSearch={fetchStockData} />
            <StockInfo stock={stock} />
            <div className="actions">
                <button onClick={buyStock} disabled={!stock}>Buy</button>
                <button onClick={sellStock} disabled={!stock}>Sell</button>
            </div>
            <Portfolio portfolio={portfolio} />
        </div>
    );
};

export default App;
				
			

Step 6: Styling the Application

Add some CSS to make the app look clean and user-friendly. Update the App.css file:

				
					/* src/App.css */

body {
    font-family: Arial, sans-serif;
    background-color: #f0f0f0;
    margin: 0;
    padding: 0;
}

.App {
    text-align: center;
    padding: 20px;
}

header {
    background-color: #333;
    color: white;
    padding: 20px;
}

.stock-search {
    margin: 20px 0;
}

.stock-search input {
    padding: 10px;
    width: 250px;
    margin-right: 10px;
    border-radius: 5px;
    border: 1px solid #ccc;
}

.stock-search button {
    padding: 10px 20px;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

.stock-search button:hover {
    background-color: #0056b3;
}

.stock-info, .portfolio {
    background-color: white;
    margin: 20px auto;
    padding: 20px;
    border-radius: 5px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    width: 80%;
    max-width: 600px;
}

.actions {
    margin: 20px 0;
}

.actions button {
    padding: 10px 20px;
    margin: 0 10px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

.actions button:disabled {
    background-color: #ccc;
    cursor: not-allowed;
}

.actions button:not(:disabled) {
    background-color: #28a745;
    color: white;
}

.actions button:not(:disabled):hover {
    background-color: #218838;
}
				
			

Step 7: Running the Application

  • Replace "your_api_key_here" with your actual Alpha Vantage API key in App.js.

  • Start the React development server:

				
					npm start
				
			
  • Open your browser and navigate to http://localhost:3000 to see your stock trading app in action.

Conclusion

You have now built a fully functional stock trading web application using React.js, complete with stock searching, buying, and selling features. This project is a great starting point for learning how to integrate APIs with a React frontend, manage state, and build interactive user interfaces. You can further extend this application by adding features like a transaction history, user authentication, and more detailed stock analysis. Happy coding!