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

如何在两层嵌套的React组件中更新根组件的state

Solution for React State Management Across Components

Hey there! Let's fix this state management issue step by step. Since you're new to React, the simplest approach here is to use prop drilling (passing state and update functions down through components) — it's ideal for small component trees like yours. Here's how to adjust each component:

1. Update App.js: Pass State and Update Function to Listing

First, we'll add a method in App to handle category changes, then pass both the selectedCategory state and this method to the Listing component:

class App extends Component {
  state = {
    tours: {},
    selectedCategory: ""
  };

  loadData() {
    fetch(API)
      .then(response => response.json())
      .then(json => {
        console.log(json);
        this.setState({ tours: json });
      });
  }

  // Add this method to update the selected category state
  handleCategoryChange = (categoryId) => {
    this.setState({ selectedCategory: categoryId });
    // You can add filtering logic for tours here later, e.g.:
    // const filteredTours = this.state.tours.filter(tour => tour.categoryId === categoryId);
    // this.setState({ filteredTours });
  }

  componentDidMount() {
    this.loadData();
  }

  render() {
    return (
      <div className="tour-container">
        {/* Pass state and update function as props to Listing */}
        <Listing 
          selectedCategory={this.state.selectedCategory}
          onCategoryChange={this.handleCategoryChange}
        />
      </div>
    );
  }
}

export default App;

2. Update Listing.js: Pass Props to Categories

Listing acts as a middleman here — it just needs to forward the props it receives from App to the Categories component:

import React, { Component } from 'react';
import Categories from './Categories.js';

class Listing extends Component {
  render() {
    const { selectedCategory, onCategoryChange } = this.props;
    return (
      <div>
        {/* Forward props to Categories */}
        <Categories 
          selectedCategory={selectedCategory}
          onCategoryChange={onCategoryChange}
        />
      </div>
    );
  }
}

export default Listing;

3. Update Categories.js: Use Props Instead of Local State

Remove the local selectedCategory state from Categories, and use the props to handle clicks and track the active category:

import React, { Component } from 'react';

class Categories extends Component {
  handleCategoryClick = (id, e) => {
    console.log(id);
    // Call the update function from props instead of setting local state
    this.props.onCategoryChange(id);
  }

  render() {
    const { selectedCategory } = this.props;
    return (
      <div className="tour-categories">
        <ul className="tour-categories-list">
          {/* Add active class to the selected category */}
          <li 
            onClick={(e) => this.handleCategoryClick(1, e)}
            className={selectedCategory === 1 ? 'active' : ''}
          >Food & Drink</li>
          <li 
            onClick={(e) => this.handleCategoryClick(2, e)}
            className={selectedCategory === 2 ? 'active' : ''}
          >Whisky Distilleries</li>
          <li 
            onClick={(e) => this.handleCategoryClick(3, e)}
            className={selectedCategory === 3 ? 'active' : ''}
          >TV & Film Location</li>
          <li 
            onClick={(e) => this.handleCategoryClick(4, e)}
            className={selectedCategory === 4 ? 'active' : ''}
          >City Tour</li>
          <li 
            onClick={(e) => this.handleCategoryClick(5, e)}
            className={selectedCategory === 5 ? 'active' : ''}
          >Castles</li>
          <li 
            onClick={(e) => this.handleCategoryClick(6, e)}
            className={selectedCategory === 6 ? 'active' : ''}
          >Golf </li>
          <li 
            onClick={(e) => this.handleCategoryClick(7, e)}
            className={selectedCategory === 7 ? 'active' : ''}
          >Shopping</li>
          <li 
            onClick={(e) => this.handleCategoryClick(8, e)}
            className={selectedCategory === 8 ? 'active' : ''}
          >Out Door Activities</li>
          <li 
            onClick={(e) => this.handleCategoryClick(9, e)}
            className={selectedCategory === 9 ? 'active' : ''}
          >Spa & Wellness</li>
          <li 
            onClick={(e) => this.handleCategoryClick(10, e)}
            className={selectedCategory === 10 ? 'active' : ''}
          >Boat Tours & Water Sports</li>
          <li 
            onClick={(e) => this.handleCategoryClick(11, e)}
            className={selectedCategory === 11 ? 'active' : ''}
          >Zoo & Aquariums</li>
        </ul>
      </div>
    );
  }
}

export default Categories;

How This Works

  • The selectedCategory state lives in the top-level App component, where it can be used to filter the tours data later.
  • We pass the state and an update function (onCategoryChange) down through Listing to Categories.
  • When a category is clicked in Categories, it triggers the onCategoryChange function, which updates the state in App.
  • All components receive the updated state via props, so the selected category is consistent across the app.

For larger apps, you might look into state management libraries like Redux or React Context, but prop drilling is the simplest and most straightforward solution for your current setup.

内容的提问来源于stack exchange,提问作者user3725781

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:59:07