ComponentWillMount被调用两次,渲染被调用两次。同样,在减速器完成之前调用渲染。 React和Redux

时间:2018-07-23 03:36:39

标签: react-redux

这是我的控制台:

action: {type: "@@redux/PROBE_UNKNOWN_ACTION_u.0.n.a.j.f"}
action: {type: "@@redux/INIT2.4.j.c.2.m"}
in component will mount
inside the hangout_list render method
in component will mount
inside the hangout_list render method
Uncaught TypeError: Cannot read property 'map' of undefined
    at HangoutList.render (bundle.js:22963)
    at finishClassComponent (bundle.js:11048)
    at updateClassComponent (bundle.js:11016)
    at beginWork (bundle.js:11641)
    at performUnitOfWork (bundle.js:14473)
    at workLoop (bundle.js:14502)
    at HTMLUnknownElement.callCallback (bundle.js:2759)
    at Object.invokeGuardedCallbackDev (bundle.js:2797)
    at invokeGuardedCallback (bundle.js:2846)
    at replayUnitOfWork (bundle.js:13977)
...
bundle.js:12302 The above error occurred in the <HangoutList> component:
    in HangoutList (created by Connect(HangoutList))
    in Connect(HangoutList) (created by App)
    in div (created by App)
    in App
    in Provider

...
action: {type: "FETCH_HANGOUTS", payload: {…}}
inside fetch hangouts in the reducer
action: {type: "FETCH_HANGOUTS", payload: {…}}
inside fetch hangouts in the reducer

如您所见,有些console.logs被调用了两次,并且我们有一个未定义的错误,表明未设置某些状态数据。

我在localhost:8080上有一个react-redux应用程序,该应用程序使用ReduxPromise并正在对localhost:3000进行api调用,成功后...数据返回。它永远不会在组件尝试渲染之前设置时间。我该怎么办?

我的代码:

我的主要index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise'

import App from './components/app';
import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>
  , document.querySelector('.container'));

我的动作

import axios from 'axios'

export const ROOT_URL = 'http://localhost:3000';

export const FETCH_HANGOUTS = 'FETCH_HANGOUTS';

export function fetchHangouts() {
  const path = 'api/v1/hangouts'
  const url = `${ROOT_URL}/${path}`;
  const request = axios.get(url);

  return {
    type: FETCH_HANGOUTS,
    payload: request
  };
}

我的App组件:

import React, { Component } from 'react';
import HangoutList from '../containers/hangout_list'

export default class App extends Component {
  render() {
    return (
      <div>
        <HangoutList />
      </div>
    );
  }
}

HangoutList容器:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchHangouts } from '../actions/index';

class HangoutList extends Component {
  renderHangouts(hangoutData) {
    const type = hangoutData.type;
    const additional_info = hangoutData.additional_info;
    const hangoutKey = hangoutData.id;

    return (
      <tr key={hangoutKey}>
        <td> {type} </td>
        <td> {additional_info} </td>
      </tr>
    )
  }

  componentWillMount() {
    console.log("in component will mount");
    this.props.fetchHangouts();
  }

  render() {
    console.log("inside the hangout_list render method");

    return (
      <table className="table table-hover">
        <thead>
        <tr>
          <th>Type</th>
          <th>Details </th>
        </tr>
        </thead>
        <tbody>
        {this.props.hangouts.map(this.renderHangouts)}
        </tbody>
      </table>
    )
  }
}

function mapStateToProps({ hangouts }) { // es6 shorthand. It's the same as if state was the argument and { hangouts: state.hangouts } was in the return section.
  return { hangouts };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchHangouts }, dispatch)
}

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

最后是我的减速器:

import { FETCH_HANGOUTS } from "../actions/index";

export default function(state = [], action) {
  console.log("action:", action);

  switch (action.type) {
    case FETCH_HANGOUTS:
      // return state.concat([ action.payload.data ]); // don't use push. concat creates a new array, while push mutates the old one. YOu   want to create a new array, not mutate the old one.
      console.log("inside fetch hangouts in the reducer")
      return action.payload.data
  }

  return state;
}

有人知道问题出在哪里吗?我基本上不知道为什么某些console.logs运行两次,为什么我的api调用(在ComponentWillMount中调用)在容器渲染之前无法完成。我以为ReduxPromise是应该用来解决此问题的中间件?

0 个答案:

没有答案