search

Home  >  Q&A  >  body text

UI in Reactjs not being updated

<p>I am learning React and learned some basics, so I used this knowledge to make this basic project. I'm making a simple note-saving app using React and Firebase. </p> <p>The data is transferred to the Firebase database flawlessly. </p> <p>Get data. </p> <p>The problem I am facing is that the data fetched is not updated in the UI. </p> <p><br /></p> <pre class="snippet-code-js lang-js prettyprint-override"><code>import { useEffect, useState } from 'react'; import { AiFillCaretUp } from 'react-icons/ai'; import './Card.css'; export default function Card(props) { const [showPara, setShowPara] = useState(false); const [data, setData] = useState([]); console.log('inside card'); useEffect(() => { let notesData = []; console.log('inside UseEffect'); const fetchNote = async () => { const response = await fetch('https://notes-keeper-react-default-rtdb.firebaseio.com/notes.json'); const data = await response.json(); for (const key in data) { notesData.push({ id: key, title: data[key].title, note: data[key].note }); } }; fetchNote(); // console.log(notesData); setData(notesData); }, []); const toggleHandler = () => { setShowPara((preVal) => !preVal); }; const paraClass = showPara ? 'card-para toggle' : 'card-para'; const rotate = showPara ? 'icon rotate' : 'icon'; return ( <div className='container'> {console.log('inside card container', data)} {data.map((card) => ( <div className='card' key={card.id}> <div className='card-title' onClick={toggleHandler}> <h3>{card.title}</h3> <AiFillCaretUp className={rotate} /> </div> <div className={paraClass}> <p>{card.note}</p> </div> </div> ))} </div> ); }</code></pre> <p><br /></p> <p>Show data here</p> <pre class="brush:php;toolbar:false;">{console.log('inside card container', data)}</pre> <p>But it doesn’t work</p> <pre class="brush:php;toolbar:false;">{data.map((card) => ( <div className='card' key={card.id}> <div className='card-title' onClick={toggleHandler}> <h3>{card.title}</h3> <AiFillCaretUp className={rotate} /> </div> <div className={paraClass}> <p>{card.note}</p> </div> </div> ))} </div></pre> <p>I hope you understand the problem. </p>
P粉649990163P粉649990163472 days ago650

reply all(1)I'll reply

  • P粉276064178

    P粉2760641782023-08-15 13:57:52

    One way is to write like this:

    useEffect(() => {
        let notesData = [];
        const fetchNote = async () => {
          const response = await fetch('https://notes-keeper-react-default-rtdb.firebaseio.com/notes.json');
          const data = await response.json();
          for (const key in data) {
            notesData.push({ id: key, title: data[key].title, note: data[key].note });
          }
          setData(notesData); // 在这里数据已经准备好了
        };
        fetchNote();
      }, []);

    fetchNote is an asynchronous function, so it takes some time to complete the task and get the data. Therefore, you should wait for the data to be ready, unfortunately when you use setData(notesData) immediately after calling fetchNote(), the data is not ready yet.

    Or you can return the data inside the async function and automatically return another promise that resolves to the required data, and then you can update your data:

    useEffect(() => {
        let notesData = [];
        const fetchNote = async () => {
          const response = await fetch('https://notes-keeper-react-default-rtdb.firebaseio.com/notes.json');
          const data = await response.json();
          for (const key in data) {
            notesData.push({ id: key, title: data[key].title, note: data[key].note });
          }
          return notesData; // 返回一个解析为 'notesData' 的 promise
        };
    
        fetchNote()
          .then((updatedData) => {
            setData(updatedData);
          })
      }, []);

    reply
    0
  • Cancelreply