简体   繁体   中英

React firebase get data from .on('value')

I am getting data from firebase in react, but I am not able to pass on that data as the variables are defined internally. Following is what I am trying to do.

function getCommentNums(item){
  const formRef = database.ref(
    `/comments/${form_id}/${instanceId}/${item.id}`
  );
  console.log('formref = ', formRef)
  formRef.on('value', async(snap)=>{
    const commentsArr = (await snap.val()) ?? [];
    console.log('commentArr=', commentsArr.length)
    setCommentLen(commentsArr.length)
  })
  return someNum
}

then in main return statement getcommentnums is called inside accordion

{questions.map((item, index) => (
    <Accordion
      key={index}
      id={
        "question-" +
        (noOfQuestionsPerPage * (page - 1) + 1 + index)
      }
      question={item}
      questionNo={noOfQuestionsPerPage * (page - 1) + 1 + index}
      //match vs item.id
      commentNums = {getCommentNums(item)}
      onBlur={handleClickSave}
      onClickComments={onClickComments}
      onChangeAnswer={onChangeAnswer}
      answers={answers}
      onClickLastValue={onClickLastValue}
      disabled={form.is_submitted}
    />
))}

I am trying someNum to be commentsArr.length , which is supposed to be some integer. This function is going to be called in some child component to display value of commentNums. Multiple child components are going to be on one page and each would be calling above fn to get there respective commentNums.

I have tried using set state, but that just causes infinite loop.

Can someone show me how to send commentArr.length value forward?

While you call setCommentLen(commentsArr.length) to update the commentLen state variable, your rendering code still tries to render the return value of getCommentNums , which won't work.

The proper way to implement this is to:

  1. Modify your loader function to no longer return any value, and only update the state.

     function loadCommentCount(item){ const formRef = database.ref(`/comments/${form_id}/${instanceId}/${item.id}`); formRef.on('value', async(snap)=>{ const commentsArr = (await snap.val())?? []; setCommentLen(commentsArr.length) }) }
  2. Call this loader function outside of the rendering code, for example when the component is created, typically in a useState handler.

     useState(() => { questions.map((item, index) => ( loadCommentCount(item); }) }, [questions])
  3. Then render the value from the state.

     commentNums = {commentCount}

Also see:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM