Javascript React/Redux can';t在状态为的数组上迭代

Javascript React/Redux can';t在状态为的数组上迭代,javascript,reactjs,redux,Javascript,Reactjs,Redux,我正在学习React/Redux,在将我的单页web应用程序转换为框架/范例时遇到了一个问题。我试图做的是让web应用程序的初始状态有一个数组,该数组将由API请求中的对象填充,该数组称为“make”。我想这样做,这样我就可以显示“使”从API在网站的第一页加载时。这可以在下面的index.js文件中看到: import App from './App'; import './index.css'; import configureStore from './redux/store' impor

我正在学习React/Redux,在将我的单页web应用程序转换为框架/范例时遇到了一个问题。我试图做的是让web应用程序的初始状态有一个数组,该数组将由API请求中的对象填充,该数组称为“make”。我想这样做,这样我就可以显示“使”从API在网站的第一页加载时。这可以在下面的
index.js
文件中看到:

import App from './App';
import './index.css';
import configureStore from './redux/store'
import { Provider } from 'react-redux'

let makesUrl = 'the url to the API'
let cached = cache.get(makesUrl)
let makes = []

// Future cache setup.
if(!cached) {
    console.log("NOT CACHED")
}
else {
    console.log("CACHED")
}

// Get the makes via API.
fetch(makesUrl).then((response) => {
    // Pass JSON to the next 'then'
    return response.json()
}).then((json) => {
    json.makes.forEach((make) => {
        makes.push(make)
    })
})

let initialState = {
  grids: [],
  makes: makes
}

let store = configureStore(initialState)

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
在chrome开发工具中,我可以看到API调用成功,状态显示为
makes:Array[62]
,其中包含62个对象,但是如果我在控制台中记录这些make传递到的组件中的数组长度,如下图所示,它表示长度为0,数组的每个索引都是未索引的

import React, { Component } from 'react'

    class MakeButtons extends Component {

        handleClick(event) {
            event.preventDefault()
            console.log("CLICK")
        }

        render() {
            return(
                <div>
                    {
                        console.log(this.props.makes.length)
                    }
                </div>
            )
        }
    }

    export default MakeButtons
import React,{Component}来自“React”
类MakeButtons扩展组件{
handleClick(事件){
event.preventDefault()
console.log(“单击”)
}
render(){
返回(
{
console.log(this.props.makes.length)
}
)
}
}
导出默认生成按钮

这基本上是我在过去几个小时里一直试图弄清楚的,因此我可以使用
forEach
map
函数返回数组中每个对象的链接/按钮,但是目前这不起作用,尽管开发工具显示状态正常。如有任何帮助/解释,将不胜感激

所以你只需要为你的init设置一个action/reducer,然后你可以在
componentWillMount
componentDidMount
中调用它,因为它们在加载你的应用程序时只被调用一次

按照您现在所做的方式,您有一个fetch和一个使用fetch中的数据的应用程序,该数据不会等待异步调用在启动应用程序之前完成

您只需要创建您的初始操作,因此您的操作创建者应该是:

   import * as services from './services';

   function initMyAppDispatcher(type, data, status) {
       return {
          type, 
          data,
          status
        };
   }


   export function initMyApp(dispatch, makesUrl) {
      dispatch(initMyAppDispatcher(actions.INIT_APP, {}, 'PENDING');

      return services.myInitCall(makesUrl)
         .then((data) =>
             dispatch(initMyAppDispatcher(actions.INIT_APP, data, 'SUCCESS'),
            (error) =>
             dispatch(initMyAppDispatcher(actions.INIT_APP, error, 'FAILURE'),
         )
         .catch(yourErrorHandling);
   }
不管您想如何实现它,只要确保将其作为承诺导出回来即可。在您的情况下,您可以将该行替换为
fetch(makesUrl)
,只要您有权访问该行。然后将其设置为这样,您可以这样设置减速器:

   case actions.INIT_APP:
            if (action.status) {
                switch (action.status) {
                    case PENDING:
                        //you can use this to create a "loading" state like a spinner or whatever
                        return state;
                    case SUCCESS:
                        // note: this is immutablejs syntax, use whatever you prefer
                        return state.set('makes', action.data);
                   case FAILURE:
                        return state;

                    default:
                        return state;
                }
            }
            return state;
需要注意的一点是,我在action creators中使用了dispatch,因为我使用了
mapDispatchToProps
来代替
mapToProps
。因此,您的容器看起来如下所示:

import * as actionCreators from './action-creators';

function mapStateToProps(state) {

    return {
        makes: state.get('makes')
    };
}

function mapDispatchToProps(dispatch, ownProps) {
    return {
        initMyApp: actionCreators.initMyApp.bind(null, dispatch)
    };
}


export default function(component = Component) {
    return connect(mapStateToProps, mapDispatchToProps)(component);
}
然后在组件
componentWillMount
componentDidMount
中,传入并调用init函数

   componentDidMount() {
       this.props.initMyApp();

   }

在回迁之前,您正在初始化应用程序。此外,您应该使init调用成为一个action/reducer,这将使这个过程更干净,并且您的应用程序不必基于第一个fetch调用挂起。@ajmajma啊,这很有意义!在这种情况下,componentWillMount方法是否适合分派操作?是的,componentWillMount或componentDidMount都适用,因为它们只在加载应用程序时被调用一次。您可以使用异步调用创建一个更新状态的操作,并在其中一个中调用它。好的,非常感谢您的帮助!没问题!如果您需要帮助,或者希望我用一个例子来回答这个问题,请告诉我,我会为您设置一个。
   componentDidMount() {
       this.props.initMyApp();

   }