Как использовать один компонент для отображения массива значений

#javascript #reactjs

#javascript #reactjs

Вопрос:

В следующем коде я жестко закодировал 4 раздела: «общее благосостояние», «путеводитель», «медицинский справочник», «руководство по аренде» для карты, используя взамен несколько одинаковых компонентов карты. Теперь я использовал массив категорий, чтобы сохранить эти четыре элемента и попытался отобразить каждый из них из массива в карточку, просто используя один компонент card вместо того, чтобы создавать card снова и снова для каждого из них. Короче говоря, я пытаюсь улучшить возможность повторного использования кода при добавлении новой информации в массив категорий. Как я могу этого добиться?

 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 amp;amp; 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>
    );
}
  

Ответ №1:

В основном вам нужны ваши жестко закодированные данные в массив, который вы можете отобразить (), например:

 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>
)  

Ответ №2:

Можете ли вы попробовать это, у нас может быть постоянный файл, предоставляющий значение массива, как я сделал для переменной accordianData

 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 amp;amp; category.length !== 0) {
      console.log('post is', post)
    }
  }, [post])

  const accordionData = [{
    title: 'general welfare',
    body: ['lugguage info', 'flight info']
  }, {
    title: 'travel guide',
    body: [`let's go to vegas`, 'travel with parents', 'christmas plan']
  }, {
    title: 'medical guide',
    body: ['save $600 in 15mins']
  }, {
    title: 'rental guide',
    body: ['great deal around neighborhood']
  }]

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

                    <Accordion.Collapse eventKey="0">
                      <Card.Body>
                        {data.body.forEach((bodyData, bodyIndex) => (
                          <>
                            {bodyIndex ? <hr /> : null}
                            <li value={1} onClick={e => setId(e.target.value)}>{bodyData}</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>
  );
}