reducer数据未正确呈现

时间:2017-09-17 13:41:46

标签: arrays reactjs react-native ecmascript-6 react-redux

从api调用返回的数据是:

[
    {
        "1": {
            "id_post": 1,
            "id_user": "user01",
            "text": "post1 text",
            "parentId": 11
        }
    },
    {
        "2": {
            "id_post": 2,
            "id_user": "user01",
            "text": "post2 text",
            "parentId": 11
        }
    },
    {
        "3": {
            "id_post": 3,
            "id_user": "user01",
            "text": "post3 text",
            "parentId": 22
        }
    }
]

在reducer中,initialState是:

const initialState = {
    posts: [],         // <= Have tried with posts: {} and posts: ''
    isFetching: false,
    error: {}
}

填充posts的方式是:

case "FETCHING_POSTS_SUCCESS":
  return {
    ...state,
    isFetching: false,
    posts: action.data
 }

我可以mapStateToProps这些帖子,如果我console.log("POSTS: ", this.props.posts)我得到了:

帖子:

0 : {1: {…}}
1 : {2: {…}}
2 : {3: {…}} 

这就是以下功能不起作用的原因吗?:

renderposts = (parentId = 1) => {
  return Object.keys(this.props.posts)
    .filter(id_post => this.props.posts[id_post].parentId == parentId)
    .map((key, idx) => {
        const post = this.props.post[key];
        return(
            <View>
                <Text> { post.id_post } - { post.text } </Text>
            </View>
        );
    });
}

我没有收到任何错误,但也没有任何错误。

我在想是否将POSTS返回为:

{1: {…}}
{2: {…}}
{3: {…}} 
在控制台中

(所以它以这种方式呈现),它将起作用。如果是这样,我该怎么做?

非常感谢。

3 个答案:

答案 0 :(得分:2)

您的数据为array而不是object,因此您无法对其进行Object.keys
你首先应该.map然后遍历对象的密钥。

实施例:

const posts = [
    {
        "1": {
            "id_post": 1,
            "id_user": "user01",
            "text": "post1 text",
            "parentId": 11
        }
    },
    {
        "2": {
            "id_post": 2,
            "id_user": "user01",
            "text": "post2 text",
            "parentId": 11
        }
    },
    {
        "3": {
            "id_post": 3,
            "id_user": "user01",
            "text": "post3 text",
            "parentId": 22
        }
    }
]

const View = ({postId,postText }) => {
  return(
    <div>{`${postId} - ${postText}`}</div>
  );
}

const renderposts = (parentId = 1) => {
 return posts.map(obj => {
    return Object.keys(obj)
    .filter(id => obj[id].parentId == parentId)
    .map((key, idx) => {
        const post = obj[key];
        return(
            <View postId={post.id_post} postText={post.text}/>
        );
    });
  });
}

class App extends React.Component{
  render(){
    return(
    <div>
      {renderposts(11)}
    </div>
    );
  }
}

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

答案 1 :(得分:0)

Object.keys在数组中时,您不应该使用posts

renderposts = (parentId = 1) => {
    return this.props.posts
        .filter((post) => post.parentId === parentId)
        .map((post) => {
            return(
                <View>
                    <Text> { post.id_post } - { post.text } </Text>
                </View>
            );
       });
}

答案 2 :(得分:0)

您可以在渲染方法中console this.props.posts。 有时您的组件将在从api获取数据之前呈现。 为确保不会发生这种情况,您应该将另一个变量isFetched保留为

const initialState = {
    posts: [],         
    isFetching: false,
    isFetched: false
    error: {}
}

在api成功之后调用make是真的

case "FETCHING_POSTS_SUCCESS":
  return {
    ...state,
    isFetching: false,
    posts: action.data,
    isFetched: true
 }

所以在渲染中你可以检查

if(this.props.isFetched){
//do you code
}
else
return;