【问题标题】:Data not appearing in component when hooking up action creators, reducers with redux-thunk使用 redux-thunk 连接动作创建者、reducer 时数据未出现在组件中
【发布时间】:2018-05-07 10:21:47
【问题描述】:

我在将所有部分放在一起以便能够在我的组件上显示数据时遇到问题。我可以在 chrome 控制台上看到数据显示,并且页面上没有任何错误,但数据没有出现在我的组件上。

如果有人可以帮助我了解我做错了什么和/或我可以做得更好

下面是带有代码的sn-p。

actionCreator

// @flow
// [TODO]: Add flow

import axios from 'axios';

const ROOT_URL = `https://toilets.freska.io/toilets`;

// const Actions = /* [TODO]: add flow */

export const FETCH_TOILETS = 'FETCH_TOILETS';
export const FETCH_TOILETS_PENDING = 'FETCH_TOILETS_PENDING';
export const FETCH_TOILETS_ERROR = 'FETCH_TOILETS_ERROR';

export function fetchToilets() {
    const url = `${ROOT_URL}`;  
    const request = axios.get(url);

    return dispatch => {
    console.log(`IN ACTION fetchToilets`);

    dispatch({ type: FETCH_TOILETS_PENDING })
    axios.get(url)
    .then(
      response => dispatch({
        type: FETCH_TOILETS,
        payload: response
    }),
      error => dispatch({ type: FETCH_TOILETS_ERROR, payload: error })
    );
    };
};

reducer_cardList & rootReducer

// @flow
// [TODO]: Add flow

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

// type State = {} /* [TODO]: add @flow */

const initialState = [];

const CardListReducer = (state: State = initialState, action:Action ): State => {
    switch(action.type) {
        case FETCH_TOILETS:
            return [  ...state, action.payload.data ];
        default:
            state;
    }
    return state;
}

export default CardListReducer;


// rootReducer

// @flow
// [TODO]: Add flow
import { combineReducers } from 'redux';
import CardListReducer from './reducer_cardList';

const rootReducer = combineReducers({
  toilets: CardListReducer
});

export default rootReducer;

index.js

// @flow
// [TODO]: add @flow

import * as React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware, compose } from 'redux';

import App from './App';
import rootReducer from './reducers';

import './index.css';

import registerServiceWorker from './registerServiceWorker';

const rootElement = document.getElementById('root');

const configueStore = createStore(
    rootReducer,
    applyMiddleware(thunk)
);

ReactDOM.render(
  <Provider store={configueStore}>
    <App />
  </Provider>
  ,
  rootElement
);

registerServiceWorker();

CardList.js

/* @flow */
// [TODO]: add flow

import * as React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchToilets } from '../../actions';


import CardItem from '../../components/CardItem/CardItem';
import './CardList.css';


type CardListProps = {
  cards?: React.Node<any>
}

class CardList extends React.Component<CardListProps,{}> {

  renderToilet() {
    const toilets = this.props.toilets;
    //const toilet = toilets.map(e => e.id)

    console.log(`These are all the toilets: ${JSON.stringify(toilets)}`); // [[{"id":1,"map_id":"TOILET1","queue_time":1800,"queue_level":1,"type":"male","location":""}, ...etc
    //console.log(`This is the toilet info: ${JSON.stringify(toilet)}`);

    const id = toilets.map(toilet => toilet.id);
    const mapId = toilets.map(toilet => toilet.map_id);

    console.log(`This is the id: ${JSON.stringify(id)} and the mapId: ${JSON.stringify(mapId)}`); // This is the id: [null] and the mapId: [null]

    // const queueTime = data.map(toilet => toilet.queue_time);
    // const queueLevel = data.map(toilet => toilet.queue_level);
    // const type = data.map(toilet => toilet.type);
    // const location = data.map(toilet => toilet.location);

    return (
      <li key={id}> 
       <p>{mapId}</p>
       {/*<p>{queueTime}</p>
       <p>{queueLevel}</p>
       <p>{type}</p>
       <p>{location}</p> */}
      </li>
    )
  }

  componentDidMount() {
    console.log(`fetchToilets() actionCreator: ${this.props.fetchToilets()}`);
    this.props.fetchToilets();
  }


  render() {
        return(
      <section>      
            <ul className='card-list'>
          {/* { this.props.toilet.map(this.renderToilet) } */}
          { this.renderToilet() } 
            </ul>
      </section>
        )
    }
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({ fetchToilets }, dispatch);
}

const mapStateToProps = ({ toilets }) => {
  return { toilets }
};

export default connect(mapStateToProps, mapDispatchToProps)(CardList);

【问题讨论】:

    标签: javascript reactjs redux redux-thunk


    【解决方案1】:

    你需要像这样更新你的 reducer

    const CardListReducer = (state: State = initialState, action:Action ): State => {
        switch(action.type) {
            case FETCH_TOILETS:
                return [  ...state, ...action.payload.data ];
            default:
                state;
        }
        return state;
    }
    

    你的旧线

    return [  ...state, action.payload.data ]
    

    替换为

     return [  ...state, ...action.payload.data ];
    

    如果你想每次都加载,那么你可以简单

        return  action.payload.data;
    

    和你的渲染功能

    renderToilet() {
        const toilets = this.props.toilets;   
    
      return arr.map((item, id) =><li key={id}> 
           <p>{item.id}</p>
           {/*<p>{queueTime}</p>
           <p>{queueLevel}</p>
           <p>{type}</p>
           <p>{location}</p> */}
          </li>)
    
    
      }
    

    【讨论】:

    • 这解决了问题,谢谢。不过我还有一个问题。我想将 renderToilet 函数中的所有数据提取到 Card.js 组件中。这是可能的吧?谢谢
    • 是的,你想在ul标签中打印什么?
    • 是的。现在我将我所有的objs 都放在一个&lt;li&gt;&lt;/li&gt; 标记中,但我想为每个&lt;li&gt;&lt;/li&gt; 获取一个obj,然后将其移至外部组件
    猜你喜欢
    • 1970-01-01
    • 2020-05-23
    • 2021-03-03
    • 2017-08-02
    • 2020-04-10
    • 2016-10-18
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    相关资源
    最近更新 更多