Gre*_*nce 5 javascript reactjs redux react-redux
我有一个组件TreeNav,其数据来自api调用。我已经设置了reducer / action / promise和所有管道,但是在组件渲染中,当我对数据调用map()时,得到“ Uncaught TypeError:无法读取未定义的属性'map'”。
故障排除显示TreeNav render()被调用两次。第二次是从api返回数据之后。但是由于第一个render()错误,第二个render()从未运行。
这是我的代码文件:
-------- reducers / index.js ---------
import { combineReducers } from 'redux';
import TreeDataReducer from './reducer_treedata';
const rootReducer = combineReducers({
treedata: TreeDataReducer
});
export default rootReducer;
Run Code Online (Sandbox Code Playgroud)
-------- reducers / reducer_treedata.js ---------
import {FETCH_TREE_DATA} from '../actions/index';
export default function (state=[], action) {
switch (action.type) {
case FETCH_TREE_DATA: {
return [action.payload.data, ...state];
}
}
return state;
}
Run Code Online (Sandbox Code Playgroud)
-------- actions / index.js --------
import axios from 'axios';
const ROOT_URL = 'http://localhost:8080/api';
export const FETCH_TREE_DATA = 'FETCH_TREE_DATA';
export function fetchTreeData () {
const url = `${ROOT_URL}/treedata`;
const request = axios.get(url);
return {
type: FETCH_TREE_DATA,
payload: request
};
}
Run Code Online (Sandbox Code Playgroud)
-------- components / tree_nav.js --------
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {fetchTreeData} from '../actions/index';
class TreeNav extends Component {
constructor (props) {
super(props);
this.state = {treedata: null};
this.getTreeData();
}
getTreeData () {
this.props.fetchTreeData();
}
renderTreeData (treeNodeData) {
const text = treeNodeData.text;
return (
<div>
{text}
</div>
);
}
render () {
return (
<div className="tree-nav">
{this.props.treedata.children.map(this.renderTreeData)}
</div>
);
}
}
function mapStateToProps ({treedata}) {
return {treedata};
}
// anything returned from this function will end up as props
// on the tree nav
function mapDispatchToProps (dispatch) {
// whenever selectBook is called the result should be passed to all our reducers
return bindActionCreators({fetchTreeData}, dispatch);
}
// Promote tree_nav from a component to a container. Needs to know about
// this new dispatch method, fetchTreeData. Make it available as a prop.
export default connect(mapStateToProps, mapDispatchToProps)(TreeNav);
Run Code Online (Sandbox Code Playgroud)
就第二次渲染的错误而言,状态必须以您不期望的方式被覆盖。因此,在您的减速器中,您将返回包含任何数据的数组以及当前状态的图。使用进行连接的数组。
var a = [1,2,3]
var b = [a, ...[2,3,4]]
Run Code Online (Sandbox Code Playgroud)
编译为:
var a = [1, 2, 3];
var b = [a].concat([2, 3, 4]);
Run Code Online (Sandbox Code Playgroud)
因此,考虑到您期望有一个 Children 属性,我认为您真正想要的是一个返回对象而不是数组的减速器,并执行如下操作:
return Object.assign({}, state, { children: action.payload.data });
Run Code Online (Sandbox Code Playgroud)
从那里确保将初始状态更新为具有空子数组的对象。
由于您使用的是 props 而不是 state,所以去掉这一行。如果您需要管理组件内部的更改,状态会很有帮助。但您正在利用连接,因此这里不需要它。
this.state = {treedata: null};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5895 次 |
| 最近记录: |