我正在学习React/Redux,我在将我的一个网页应用程序转换为框架/范例时遇到了一个问题。我要做的是让web应用程序的初始状态有一个数组,该数组由来自API请求的对象填充,这个数组称为“make”。我想这样做,以便我可以显示从API的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')
);
state
和dispatch
被映射到道具,并传递到需要它们的组件,在我的App.js
文件中,如下所示:
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import './App.css'
import Head from './components/Head'
import Middle from './components/Middle'
import Foot from './components/Foot'
import actions from './redux/actions'
class App extends Component {
render() {
return (
<div className="App">
<div>
<Head />
<div className="middle container">
<Middle actions={this.props.actions} makes={this.props.makes}/>
</div>
<Foot />
</div>
</div>
);
}
}
function mapStateToProps(state) {
return state
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App)
无论如何,在chrome工具中,我可以看到API调用是成功的,并且状态显示有62个对象在其中,但是如果我控制台记录了这些组件中数组的长度,如下所示,它表示长度为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
这基本上是我在过去几个小时里一直在试图找出的,所以我可以使用forEach
或map
函数为数组中的每个对象返回链接/按钮,但是目前这种方法不起作用,尽管开发工具显示状态是正常的。任何帮助/解释都将不胜感激!
发布于 2016-08-16 14:44:12
因此,您确实需要为您的init设置一个动作/还原器,然后您可以在componentWillMount
或componentDidMount
中调用它们,因为它们在加载应用程序时只被调用一次。
按照现在的方式,您有一个fetch和一个应用程序,它使用fetch中的数据,在启动应用程序之前不等待异步调用完成。
您只想创建init操作,所以您的操作创建者应该是这样的:
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);
}
然而,Services.myInitCall想要实现它,只需确保将其导出为承诺即可。在您的情况下,只要您能够访问该行,就可以用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;
需要注意的一点是,我在操作创建者中有分派,因为我使用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();
}
https://stackoverflow.com/questions/38983618
复制