如何在reducer中的映射数组中映射嵌套数组

时间:2019-04-24 19:00:48

标签: javascript reactjs redux react-redux

TLDR:我如何更好地在initalState属性中映射数组

下面尝试尝试的代码是从like数组中检索所有postIds,并将post.idlike.postId

进行比较。

但是

  

like.postId未定义。

post.id在控制台日志上可用,帖子和点赞之间的区别是帖子是在客户端映射的,而点赞不是。因此,我尝试在化简器中进行映射,因为我需要获取为每个帖子存储的数量,并将其映射到受人尊敬的post.id。

之所以需要在likesInitialState之内设置值,是因为我需要使用以下操作来对帖子进行投票

  case ADD_LIKE:
        // console.log(action.id) // renders post id which is 2
        // console.log(state.posts) // logs posts array
        // console.log(state.posts)
            return {
            ...state,
            likes: state.likes + 1
        };

如果我做类似like[0].postId的操作,它将仅获取like.id的值。我需要能够从所有帖子中获得所有喜欢,并将like.postIdpost.id进行比较,然后设置值。

并像

一样检索计数

{this.props.likes}

只是为了了解数组的外观。

这是示例posts数组,在Posts数组中,您具有likes数组。

enter image description here

我在这里打电话的方式

export const GetPosts = () => {
    return (dispatch, getState) => {
        return Axios.get('/api/posts/myPosts')
            .then( (res) => {
                 const data = res.data
                 const likes = res.data // gets  the first item within array, and shows likes.
                 const myLikes = likes.map( (post) => {
                    return post.Likes
                 })
                 console.log(myLikes)

                 dispatch({type: GET_POSTS, data, myLikes})
             })

    }
}

减速器

export default (state = initialState, action) => {
    switch (action.type) {
     case GET_POSTS:
            console.log(action.data[0].Likes.length)
            return {
                ...state, 
                posts: action.data, // maps posts fine
                // set likes to but it only gets the first post, when it should get all posts
                likes: action.data.map( (post) => {
                    action.myLikes.map( (like) => {
                        // if(post.id === like.postId){
                            console.log(like) // renders an array of likes for all posts
                            console.log(like.postId) // renders undefined, 
                        // }
                    })
                })
        }
}

这就是它的映射方式

PostList.js

render(){
        const {posts} = this.props;
        return (
            <div>
                {posts.map((post, i) => (
                    <Paper key={post.id} style={Styles.myPaper}>

                    {/* {...post} prevents us from writing all of the properties out */}
                        <PostItem                     
                             myTitle={this.state.title} 
                             editChange={this.onChange} 
                             editForm={this.formEditing} 
                             isEditing={this.props.isEditingId === post.id} 
                             removePost={this.removePost} 
                             {...post} 
                        />
                    </Paper>
                ))}
            </div>
        )
    }
在该组件中调用

GetPosts操作

class Posts extends Component {
  state = {
    posts: [],
    loading: true,
    isEditing: false, 
  }
  async componentWillMount(){
    await this.props.GetPosts();
    this.setState({ loading: false })
    const reduxPosts = this.props.myPosts;
    const ourPosts = reduxPosts  
    console.log(reduxPosts); // shows posts line 35
  }

  render() {
    const {loading} = this.state;
    const { myPosts} = this.props
    if (!this.props.isAuthenticated) {
      return (<Redirect to='/signIn' />);
    }
    if(loading){
      return "loading..."
    }
    return (
      <div className="App" style={Styles.wrapper}>
        <h1> Posts </h1>
        <PostList posts={myPosts}/>
      </div>
    );
  }
}
const mapStateToProps = (state) => ({
  isAuthenticated: state.user.isAuthenticated,
  myPosts: state.post.posts
})
const mapDispatchToProps = (dispatch, state) => ({
  GetPosts: () => dispatch( GetPosts())
});
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(Posts));

1 个答案:

答案 0 :(得分:1)

使用Array.map()时,它将创建一个新数组,并在调用数组中的每个元素上调用提供的函数,因此您将获得一个数组数组(array每个帖子的Likes数组)以解决您的问题并获得一个Like数组,您需要使用reducer函数,如下所示:

export const GetPosts = () => {
return (dispatch, getState) => {
    return Axios.get('/api/posts/myPosts')
        .then( (res) => {
             const data = res.data
             const likes = res.data // gets  the first item within array, and shows likes.
             const myLikes = likes.reduce( (acc,post) => {
                    return acc.concat(post.Likes)
                 },[])
             console.log(myLikes)

             dispatch({type: GET_POSTS, data, myLikes})
         })
}}