0

In the following code, I hard coded 4 sections, "general welfare","travel guide","medical guide","rental guide" to the card by using multiple same card component in return. Now I used a category array to save these four element and trying to render each of them from the array to the card by just using one card component instead of creating card again and again for each of them. Shortly speaking, I am trying to improve the reusability of the code when new info is added to the category array. How can I achieve that?

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

2 Answers 2

1

You basically need your hardcoded data into an array which you can map(), For example:

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
      }
    ]
  }
]

And then in your JSX you map over the arrays:

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

Sign up to request clarification or add additional context in comments.

Comments

0

Can you try this, we can have a constant file providing the array value as I did for accordianData variable

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.