【问题标题】:How map through multiple arrays and conditional render component如何映射多个数组和条件渲染组件
【发布时间】:2019-10-16 14:44:26
【问题描述】:

现在我正在开发一个反应博客类型的应用程序,我目前在试图找出解决我的问题的最佳方法时遇到了问题。现在我有一个 postbody 组件,它使用从 redux 检索到的数据将 props 从 redux 发送到 postbody 模板组件。现在它通过一个名为 postItems 的 const 映射。我有一个函数可以返回具有相同帖子 ID 的 cmets。我需要完成的是,一旦它通过帖子正文模板进行映射,如果有 cmets 具有相同的帖子 ID,它就可以在同一个 postBodyTemplate 组件中显示这些内容。

对于我的 PostBody 组件,我有:

import React, { Component, useState, useEffect } from 'react';
import PostBodyTemplate from './postBodyTemplate';
import PropTypes from 'prop-types'
import { connect } from 'react-redux';
import { fetchPosts } from '../actions/postActions';
import { fetchComments } from '../actions/commentActions';
import axios from 'axios';

class PostBody extends Component {

  componentWillMount(){
    this.props.fetchPosts();
    // this.props.fetchComments();
}

render() {




 const reversedProps = this.props.posts.reverse();

var activeComments = [];
const getComments = async (id) => {
  const response = await axios.get("http://10.6.254.22:5000/comments/" +id);
  if (response.data.length > 0) {
    console.log(response.data);
    activeComments.push(response.data)
    return response.data
    //  activeComments = response.data;
  }
};

const postIdMap = post => post.id;
const postIds = reversedProps.map(postIdMap);
console.log(postIds);
// console.log(commentIds);

postIds.map(getComments);


  const postItems = reversedProps.map(post => (

      <PostBodyTemplate key={post.id} title={post.title} postBody={post.postBody} giphyUrl = {post.giphyUrl} userWhoPosted={post.userIdName}/>

  ));



  return (
      <div>
         <h1>{postItems}</h1>
      </div>
  )
}
}

PostBody.propTypes = {
  fetchPosts: PropTypes.func.isRequired,
  posts: PropTypes.array.isRequired,
  fetchComments: PropTypes.func.isRequired,
  // comments: PropTypes.array.isRequired
}

const mapStateToProps = state =>({
  posts: state.posts.items,
  // comments: state.comments.items
})

export default connect(mapStateToProps, { fetchPosts, fetchComments })(PostBody);

当我执行 postIds.map(getComments) 时,它会遍历帖子 ID 并检查 cmets api 端点并使用这些帖子 ID 检索帖子。它返回这样的数据:

Array(1)0: {id: 1, postId: 86, commentBody: "This is a test comment", giphyUrl: "https://media2.giphy.com/", postPicture: "pic.com", …}length: 1__proto__: Array(0)
postBody.js:41 
Array(1)
0: {id: 2, postId: 85, commentBody: "Another Comment", giphyUrl: "https://meida.com", postPicture: "pic.com", …}
length: 1
__proto__: Array(0)

我希望这些检索到的帖子也包含在帖子正文模板组件中。这是帖子正文模板,并且还在其中添加了评论组件。我也不知道这是否是最佳做法。

import React, { Component } from 'react'
import { makeStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import FavoriteIcon from '@material-ui/icons/Favorite';
import EcoIcon from '@material-ui/icons/Eco';
import IconButton from '@material-ui/core/IconButton';
import Grid from '@material-ui/core/Grid';
import Comment from './comments';



const useStyles = makeStyles(theme => ({
  root: {
    padding: theme.spacing(3, 2),
  },
}));

const fr = {
  float: 'right'
}

const giphyRes = {
    width: '300px',
    height: '300px'
}



     export default function PostBodyTemplate(props) {

         const classes = useStyles();
        //  render() {
             return (
                <Grid item xs={12} xl={8} lg={8} style={fr}>
                <Card className={classes.card}>
                <CardContent>
                <Paper className={classes.root}>
                <Typography variant="h5" component="h2" style={fr}>
                      {props.userWhoPosted} Gave A VH5 To Julio
                  </Typography>
                    <Typography variant="h5" component="h3">
                      {props.title}
                    </Typography>
                    <Typography component="p">
                      {props.postBody}
                    </Typography>
                    <img src={props.giphyUrl} style={giphyRes}/>
                </Paper>
                </CardContent>
                <CardActions>
                <IconButton aria-label="add to favorites">
                    <FavoriteIcon />
                    <div>Add Gif</div>
                  </IconButton>
                  <IconButton aria-label="share">
                    <EcoIcon />
                    <div>Add Photo</div>
                  </IconButton>
                <TextField
                  id="standard-full-width"
                  label="Reply"
                  style={{ margin: 8 }}
                  placeholder="Reply to Author"
                  fullWidth
                  margin="normal"
                  InputLabelProps={{
                    shrink: true,
                  }}
                />
                  <Button size="small">Submit</Button>
                </CardActions>

                <Comment {**THIS IS WHERE I WANT THE COMMENTS TO GO IF POST HAS COMMENTS**} />

              </Card>
              </Grid>
             )
        //  }
     }

我想要完成的是这种性质的事情,但遇到了麻烦:

const postItems = reversedProps.map(post => (

  <PostBodyTemplate key={post.id} title={post.title} postBody={post.postBody} giphyUrl = 

{post.giphyUrl} userWhoPosted={post.userIdName}/>

 **If the result of PostIds.Map(getComments) returns a post ID that equals the same Post Id as 
 above, send that information to the comments component and have it populate the comments for this 
 post specifically ** So after it populates the post body i want it to basically map through 
  reversedProps.map(getComments) after and display the comments by passing 


  ));

如果有帮助,下面是 cmets 组件。

import React, { useState, useEffect } from "react";
import PropTypes from 'prop-types'
import { connect } from 'react-redux';
import { fetchPosts } from '../actions/postActions';
import { fetchComments } from '../actions/commentActions';
import axios from 'axios';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';



const useStyles = makeStyles(theme => ({
  root: {
    padding: theme.spacing(3, 2),
  },
}));

const fr = {
  float: 'right'
}

const giphyRes = {
    width: '300px',
    height: '300px'
}


export default function Comment() {

  const classes = useStyles();


  return (
    <div>                 
          <Paper className={classes.root} value={comment.postId}>
            <Typography variant="h5" component="h3">
            {comment.commentBody}
            </Typography>
            <Typography component="p">
              {comment.userIdName} replied to the post. 
            </Typography>
        </Paper>
    </div>
  );
}


// export default Comment;

这篇文章需要通读,所以我非常感谢它。

【问题讨论】:

  • 如果我理解正确的话,您是从 REST 服务获取帖子并将它们存储在 Redux 中,然后在渲染帖子时使用另一个 REST 调用为每个帖子获取 cmets。对吗?
  • 是的,帖子是从我的帖子 Api 中调用的,它被发送到 redux 状态,cmets 是从 cmets api 中提取的,只是在那里使用而不是发送到 redux。我试图让它首先映射到帖子并发布所有帖子,并通过检查 cmets 是否有帖子 ID 来检查这些帖子是否有 cmets,如果他们有,我想将其发送到 cmets 组件显示出来。

标签: javascript reactjs


【解决方案1】:

简短的回答是,要在 react 中有条件地渲染数据,最好使用ternary operator

<YourComponent <h1>{isPostAvailable ? 'yes' : 'no'}</h1> />

在上面的代码中,如果 post 可用,则打印 yes,否则会打印 no。

【讨论】:

    【解决方案2】:

    REST 调用在 React/Redux 中是异步的,因此您应该始终将结果存储在 Redux 中以保持 UI 响应。您需要决定何时触发对 cme​​ts 的调用:可以在收到帖子时完成,或者在您确定要显示帖子时完成,但无论哪种情况,您都希望将结果放入 Redux。您可以创建一个对象,其中 postID 是键,cmets 数组是值。然后,您将通过将 Redux 状态映射到 React props 来渲染来自 Redux 的 cmets,并将 Array(如果有)传递给 Comments 组件。随着 cmets 的到来,状态的变化会触发重新渲染并填充它们。

    您需要避免直接从渲染代码触发 Comments 调用,因为这可能(可能)最终发送重复调用,因为状态的任何更改都可能导致重新渲染。当您发送调用以加载帖子时,将“PostsLoading”=true 和 PostsLoaded=false 标志添加到您的 redux 状态。在 reducer 中,将 PostsLoading 设置为 false,将 PostsLoaded 设置为 true。您可以在您的 componentWillReceiveProps 方法中检查这些,并使用这些标志中的更改来决定何时调用 cmets 服务。

    【讨论】:

      猜你喜欢
      • 2021-02-22
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 2021-09-13
      • 2017-12-16
      • 2013-01-24
      • 2021-05-29
      • 2019-05-20
      相关资源
      最近更新 更多