0

I have this function that generates dynamic components based on an API


const renderWork = () =>{
  let DOM = []

  fetch('/api/work/')
  .then(res => res.json())
  .then(res => {
    for (let i = 0; i < res.length; i++){
      DOM.push(
        <Item id={res[i]._id}>
          <Item.Image src={res[i].imageURL} />
          <Item.Content>
            <Item.Header as='a'>Watchmen</Item.Header>
            <Item.Meta>
              <span className='cinema'>{res[i].createdDate}</span>
            </Item.Meta>
              <Item.Description>{res[i].description}</Item.Description>
            <Item.Extra>
              <Label>Hi</Label>

              <Button primary floated='right'>
                Buy tickets
                <Icon name='right chevron' />
              </Button>
            </Item.Extra>
          </Item.Content>
        </Item>
      )
    }
  })

  return DOM
}

I am trying to render those items by calling the renderWork() function in the main component

The main Componenet:

function Work(){

  return (   
    <div>
      <Nav/> 
      <div style={css.body}>
      <Item.Group divided>
        {renderWork()}
      </Item.Group>

      </div>
    </div>
  )
}

I am not sure why doesn't it render on the page I tried:

  • Making the DOM a state and change it.

  • using the useEffect hook to manage the state and/or the DOM

still, the items won't render

I am using react.semantic-UI for my components

1 Answer 1

1

I would keep api and component rendering separate.

const renderWork = () => {
  return fetch('/api/work/')
    .then(res => res.json())
}
function WorkItem({item}) {
  return <Item id={item._id}>
          <Item.Image src={item.imageURL} />
          <Item.Content>
            <Item.Header as='a'>Watchmen</Item.Header>
            <Item.Meta>
              <span className='cinema'>{item.createdDate}</span>
            </Item.Meta>
              <Item.Description>{item.description}</Item.Description>
            <Item.Extra>
              <Label>Hi</Label>

              <Button primary floated='right'>
                Buy tickets
                <Icon name='right chevron' />
              </Button>
            </Item.Extra>
          </Item.Content>
        </Item>
}
function Work() {
  const [items, setItems] = useState([])

  useEffect(() => {
    renderWork()
      .then(data => {
        setItems(data)
      })
  }, [])

  return (   
    <div>
      <Nav/> 
      <div style={css.body}>
      <Item.Group divided>
        {items.map(item => <WorkItem item={item}/>}
      </Item.Group>

      </div>
    </div>
  )
}
Sign up to request clarification or add additional context in comments.

1 Comment

Think it like this. There are two states, empty list and list with fetched data, as you know renderWork() might take some time (well depends on a bandwith) so thats why you use useState hook to keep state of data, initially as [], then you use useEffect to invoke code after component has loaded, in this case renderWork() function.

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.