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

连接action creators、reducers与redux-thunk后组件不显示数据

Hey there! Let's figure out why your toilet data isn't showing up in your component even though you can see it in the Chrome console. Based on the code snippet you shared and common Redux gotchas, here are the key areas to check:

1. Make sure you're handling async actions with middleware

Since you're using axios (an async call), plain Redux can't handle action creators that return functions. You'll need to set up redux-thunk (or another async middleware) in your store configuration. Here's how to do that:

// In your store setup file (e.g., store.js)
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

// Apply thunk middleware to handle async actions
const store = createStore(rootReducer, applyMiddleware(thunk));

Then update your action creator to return an async function that dispatches the action once the API call resolves:

// Your action creator file
import axios from 'axios';
const ROOT_URL = `https://toilets.freska.io/toilets`;
export const FETCH_TOILETS = 'FETCH_TOILETS';

export const fetchToilets = () => async (dispatch) => {
  try {
    const response = await axios.get(ROOT_URL);
    // Dispatch the action with the fetched data
    dispatch({
      type: FETCH_TOILETS,
      payload: response.data
    });
  } catch (error) {
    console.error('Failed to fetch toilets:', error);
  }
};

2. Verify your reducer is updating state correctly

Your reducer needs to properly handle the FETCH_TOILETS action and return a new state object (never mutate state directly). Example reducer:

// toiletsReducer.js
import { FETCH_TOILETS } from '../actions';

const initialState = {
  toilets: [] // Initialize with an empty array
};

export default function toiletsReducer(state = initialState, action) {
  switch (action.type) {
    case FETCH_TOILETS:
      // Return a new state object with the fetched toilets
      return {
        ...state,
        toilets: action.payload
      };
    default:
      return state;
  }
}

Also, make sure this reducer is combined into your root reducer if you're using multiple reducers:

// rootReducer.js
import { combineReducers } from 'redux';
import toiletsReducer from './toiletsReducer';

export default combineReducers({
  toilets: toiletsReducer // This defines the path in your Redux state
});

3. Check if your component is connected to Redux correctly

You need to use connect from react-redux to map Redux state to component props and dispatch actions. Here's how to set that up:

// Your component file
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchToilets } from './actions';

class ToiletsList extends Component {
  // Fetch data when the component mounts
  componentDidMount() {
    this.props.fetchToilets();
  }

  render() {
    const { toilets } = this.props;

    // Handle loading state while data is fetched
    if (toilets.length === 0) {
      return <p>Loading toilets...</p>;
    }

    // Render the list of toilets
    return (
      <div className="toilets-list">
        {toilets.map(toilet => (
          <div key={toilet.id} className="toilet-item">
            <h3>{toilet.name}</h3>
            <p>Address: {toilet.address}</p>
          </div>
        ))}
      </div>
    );
  }
}

// Map Redux state to component props
const mapStateToProps = state => ({
  // Adjust the path based on your root reducer setup
  toilets: state.toilets.toilets
});

// Connect the component to Redux and inject the fetchToilets action
export default connect(mapStateToProps, { fetchToilets })(ToiletsList);

4. Confirm you're rendering data correctly

  • Double-check that the API response structure matches what you're expecting. If the data is nested (e.g., response.data.data instead of response.data), update the payload in your action creator to point to the correct array.
  • Ensure you're using a unique key prop for each item in your list (React requires this for efficient rendering).
  • Make sure you're not accidentally rendering an empty array or undefined value (use the loading state check like in the example above).

5. Verify the action is being dispatched

Use Redux DevTools (if you have it installed) to check if the FETCH_TOILETS action is being triggered, and if the payload contains the correct data. If the action isn't showing up, you might have forgotten to call this.props.fetchToilets() in your component's lifecycle method (like componentDidMount).


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:51:48