首页 > 解决方案 > 如何使用一个组件来渲染一组值

问题描述

在下面的代码中,我使用多个相同的卡片组件作为回报,将“一般福利”、“旅游指南”、“医疗指南”、“租赁指南”四个部分硬编码到卡片中。现在我使用一个类别数组来保存这四个元素,并尝试通过仅使用一个卡片组件而不是为每个元素一次又一次地创建卡片来将它们从数组中渲染到卡片。简而言之,当将新信息添加到类别数组时,我正在尝试提高代码的可重用性。我怎样才能做到这一点?

const WelfarePage = (props) => {
    const [category, setCategory] = useState([]);
    const [post,setPost] = useState([]);

    useEffect(() => {
        axios.get(`http://usccgsa.com:8080/post/category/welfare/all`)
            .then(res =>{
                setCategory(res.data)
                })
            .catch(err => {
                    console.log(err)
                 })
    },[])

    useEffect(()=>{
        console.log('category',category)
        if (category.length !==0){
            for (var i = 0; i < category.length; i++) {
                var catId = category[i].categoryId
                axios.get(`http://usccgsa.com:8080/post/cat`+catId)
                    .then(res1 =>{
                        setPost(post =>[...post,res1.data])
                    })
                    .catch(err1 => {
                        console.log(err1)
                    })
            }
        }
        },[category])

    useEffect(()=>{
        if (post.length!==0 && category.length!==0){
            console.log('post is',post)
        }
    },[post])

    return (
        <section id="blog">
            <div className="page-title">
                <h1>welfare pagee</h1>
            </div>
            <Container className="blog">
                <Container>
                    <Row>
                        <Col md="3">
                            <Accordion defaultActiveKey="0">
                                <Card>
                                    <Accordion.Toggle as={Card.Header} variant="link" eventKey="0">
                                        general welfare
                                    </Accordion.Toggle>

                                    <Accordion.Collapse eventKey="0">
                                        <Card.Body>
                                            <li value={1} onClick={e => setId(e.target.value)}>lugguage info</li>
                                            <hr/>
                                            <li value={2} onClick={e => setId(e.target.value)}>flight info</li>
                                        </Card.Body>
                                    </Accordion.Collapse>
                                </Card>
                                <Card>
                                    <Accordion.Toggle as={Card.Header} variant="link" eventKey="1">
                                        travel guide
                                    </Accordion.Toggle>

                                    <Accordion.Collapse eventKey="1">
                                        <Card.Body>
                                            <li value={3} onClick={e => setId(e.target.value)}>let's go to vegas</li>
                                            <hr/>
                                            <li value={4} onClick={e => setId(e.target.value)}>travel with parents</li>
                                            <hr/>
                                            <li value={5} onClick={e => setId(e.target.value)}>christmas plan</li>
                                        </Card.Body>
                                    </Accordion.Collapse>
                                </Card>
                                <Card>
                                    <Accordion.Toggle as={Card.Header} variant="link" eventKey="2">
                                        medical guide
                                    </Accordion.Toggle>

                                    <Accordion.Collapse eventKey="2">
                                        <Card.Body>
                                            <li value={6} onClick={e => setId(e.target.value)}>save $600 in 15mins</li>
                                        </Card.Body>
                                    </Accordion.Collapse>
                                </Card>
                                <Card>
                                    <Accordion.Toggle as={Card.Header} variant="link" eventKey="3">
                                        rental guide
                                    </Accordion.Toggle>

                                    <Accordion.Collapse eventKey="3">
                                        <Card.Body>
                                            <li value={7} onClick={e => setId(e.target.value)}>great deal around neighborhood</li>
                                        </Card.Body>
                                    </Accordion.Collapse>
                                </Card>
                            </Accordion>
                        </Col>
                        <Col md="9">
                            <div className="blog-item">
                                <div className="blog-content">
                                    <Post postUrl={post.postUrl}/>
                                </div>
                            </div>
                        </Col>
                    </Row>
                </Container>
            </Container>
        </section>
    );
}

标签: javascriptreactjs

解决方案


您基本上需要将硬编码的数据放入一个可以 map() 的数组中,例如:

const CARDS_DATA = [
  {
    header: 'general welfare',
    items: [
      {
        text: 'luggage info', 
        value: 1
      }, 
      {
        text: 'flight info', 
        value: 2
      }
    ]
  },
  {
    header: 'travel guide',
    items: [
      {
        text: 'let\'s go to vegas', 
        value: 3
      }, 
      {
        text: 'travel with parents', 
        value: 4
      }, 
      {
        text: 'christmas plan', 
        value: 5
      }
    ]
  }
]

然后在 JSX 中映射数组:

return (
          <section id="blog">
            <div className="page-title">
                <h1>welfare pagee</h1>
            </div>
            <Container className="blog">
                <Container>
                    <Row>
                        <Col md="3">
                            <Accordion defaultActiveKey="0">
                                {CARDS_DATA.map((card, index) => {
                                  return (<Card>
                                    <Accordion.Toggle as={Card.Header} variant="link" eventKey={index}>
                                        {card.header}
                                    </Accordion.Toggle>

                                    <Accordion.Collapse eventKey={index}>
                                        <Card.Body>
                                            {card.items.map(item => {
                                              return (
                                                <li value={item.value} onClick={e => setId(e.target.value)}>{item.text}</li>
                                              )
                                            })}
                                        </Card.Body>
                                    </Accordion.Collapse>
                                </Card>)
                                })}
                            </Accordion>
                        </Col>
                        <Col md="9">
                            <div className="blog-item">
                                <div className="blog-content">
                                    <Post postUrl={post.postUrl}/>
                                </div>
                            </div>
                        </Col>
                    </Row>
                </Container>
            </Container>
        </section>
)


推荐阅读