You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中如何向事件处理器传递常量至StationOne组件

How to Pass Station Names to onClick Handler and Fetch Data in StationOne Component

Hey there! Let's break down how to solve this problem while fixing a few React anti-patterns in your current code. First, let's address the main issues in your existing approach, then walk through the corrected solution.

Key Issues in Your Current Code

  • Direct DOM manipulation: Using getElementById and innerHTML goes against React's data-driven approach—we should use state to manage and render data instead.
  • Incorrect onClick usage: You're passing the StationOne component directly to onClick, which won't trigger the component properly. Instead, we need to pass data to the component via routing when the link is clicked.
  • Potential array index out-of-bounds: Your API call uses limit=2, so data.stations will only have 2 items (indexes 0 and 1)—accessing data.stations[2] will throw an error.
  • Variable name mismatches: You reference elements like nameStationEins but your HTML uses nameStationOne (and vice versa), which will cause DOM queries to fail.

Step-by-Step Solution

1. Use React State to Manage Data

First, let's replace DOM manipulation with React useState hooks to track your location and nearby stations. This keeps your data in sync with the UI automatically.

2. Pass Station Data via React Router

Instead of trying to trigger the component directly in onClick, we'll use React Router's Link component to pass station data to the StationOne component via route state. Then, StationOne can retrieve this data and make its fetch request.

Corrected HomePage Component

import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';

const HomePage = () => {
  const [currentLocation, setCurrentLocation] = useState('');
  const [nearbyStations, setNearbyStations] = useState([]);

  // Use useEffect to run geolocation on component mount
  useEffect(() => {
    const geoSuccess = (loca) => {
      const lat = loca.coords.latitude;
      const long = loca.coords.longitude;
      const url = `http://transport.opendata.ch/v1/locations?limit=3&x=${lat}&y=${long}`; // Increase limit to 3 for 2 nearby stations
      
      fetch(url)
        .then((resp) => resp.json())
        .then((data) => {
          // Update state with location and nearby stations
          setCurrentLocation(data.stations[0].name);
          // Grab the next 2 stations (indexes 1 and 2) if they exist
          setNearbyStations(data.stations.slice(1, 3));
        })
        .catch((err) => console.log('Fetch error:', err));
    };

    const geoError = (error) => {
      console.log('Geolocation error:', error);
    };

    window.navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
  }, []); // Empty dependency array runs once on mount

  return (
    <div>
      <h1>Your Location:</h1>
      <h3>{currentLocation || 'Loading...'}</h3>
      
      <h2>Stations near your location:</h2>
      {nearbyStations.length > 0 ? (
        <>
          <Link 
            to={{ 
              pathname: '/first-connection', 
              state: { stationName: nearbyStations[0].name } 
            }}
          >
            <h3>{nearbyStations[0].name}</h3>
          </Link>
          
          <Link 
            to={{ 
              pathname: '/second-connection', 
              state: { stationName: nearbyStations[1]?.name } 
            }}
          >
            <h3>{nearbyStations[1]?.name || 'No second station found'}</h3>
          </Link>
        </>
      ) : (
        <p>Loading nearby stations...</p>
      )}
    </div>
  );
};

export default HomePage;

Corrected StationOne Component

Now, in StationOne, we'll use React Router's useLocation hook to retrieve the passed station name and make the fetch request:

import React, { useState, useEffect } from 'react';
import { useLocation } from 'react-router-dom';

const StationOne = () => {
  const location = useLocation();
  const [departures, setDepartures] = useState([]);
  const stationName = location.state?.stationName;

  useEffect(() => {
    if (!stationName) return;

    // Fetch departures using the passed station name
    const url = `http://transport.opendata.ch/v1/stationboard?station=${encodeURIComponent(stationName)}`;
    
    fetch(url)
      .then((resp) => resp.json())
      .then((data) => {
        setDepartures(data.stationboard);
      })
      .catch((err) => console.log('Departure fetch error:', err));
  }, [stationName]);

  return (
    <div>
      <h1>Departures from {stationName}</h1>
      {departures.length > 0 ? (
        <ul>
          {departures.map((departure, index) => (
            <li key={index}>
              {departure.name} - {departure.to} at {new Date(departure.stop.departure).toLocaleTimeString()}
            </li>
          ))}
        </ul>
      ) : (
        <p>Loading departures...</p>
      )}
    </div>
  );
};

export default StationOne;

Key Explanations

  • State Management: We use useState to store location and station data, so React automatically re-renders the UI when data changes—no need for manual DOM updates.
  • Route State: The Link component's to prop accepts an object with a state field, which lets us pass arbitrary data to the target route.
  • useLocation Hook: In StationOne, useLocation gives us access to the route state, so we can get the station name and use it in our fetch request.
  • Error Handling: We added optional chaining (?.) to avoid errors if a second station doesn't exist, and wrapped fetch calls in catch blocks to log errors.

内容的提问来源于stack exchange,提问作者Luciano M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:17:50