简体   繁体   中英

How to update a function with useEffect (like componentDidUpdate) and use .map function to display from JSON file ReactJS

I've been trying to update a function once data has been recieved and set to a state (using useState). After that the function will use the .map function display the data into a template.

However i am getting two errors, one is 'projects.map is not a function' (btw projects is my state name, where data is stored) and inside the useEffect function which updates when projects is changed 'Expected an assignment or function call and instead saw an expression'

 import React, { useState, useEffect } from 'react'; import ProjectSummary from './projectSummary'; function ProjectList() { // setting my state const [projects, setProjects] = useState([]) // getting the data from some dummy online data when the app starts useEffect(() => { fetch('https://jsonplaceholder.typicode.com/posts') .then(response => response.json()) .then(data => setProjects({ data })) }, []); // makeing a function call postList, which stores a ternery operator const postList = () => { // The ternery operator asks if there is anything inside the porjects state projects.length ? ( // If there is something in the state, it will map out the JSON array in the 'projectSummary template projects.map(projects => { return( <div > <ProjectSummary key={projects.id} title={projects.title} author={projects.userId} date='30 september, 2019' content={projects.body}/> </div> ) }) ) : ( // If there isnt anything in the state is prints out 'Loading Data' <h1>Loading Data</h1> ); } // useEffect updates when the 'projects' stae is updated (like componentDidUpdate, and runs the function again useEffect(() => { postList() }, [projects]); return( <div className="ProjectList"> // The component should output the postList function, which should map out the array, in the template { postList } </div> ) } export default ProjectList 

You need to make some corrections to your component

import React, { useState, useEffect } from 'react';
import ProjectSummary from './projectSummary';


function ProjectList() {
  const [projects, setProjects] = useState([])

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(data => setProjects(data))

  }, []);


  return(
    <div className="ProjectList">
      {
        projects.length ?
          projects.map(projects => (
            <div>
              <ProjectSummary key={projects.id} title={projects.title} author={projects.userId} date='30 september, 2019' content={projects.body} />
            </div>
          ))
          :
          <h1>Loading Data</h1>
      }
    </div>
  )
}

export default ProjectList;

You don't need the postList function and the second useEffect .

You may want to add additional checks to determine when the posts are loading and when they're empty after loading is done, so you don't just get a loading message

try this

const [projects, setProjects] = useState([])

and

.then(data => setProjects(data))

assuming that the data is an array

First you have to set the initial projects to an empty array like this:

const [projects, setProjects] = useState([])

, because currently projects is an empty string, which does not have the map function.

For the fetch, you should write it like this:

 useEffect(async () => {
     const data = await fetch('https://jsonplaceholder.typicode.com/posts')
       .then(response => response.json())
     setProjects(data);
}, []);

Hope this helps.

Array.prototype.map() is for Array.

const [projects, setProjects] = useState('');

projects not an array.

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