简体   繁体   中英

How to run a function with default "id" on start using useEffect hook in react?

I am making a simple blog post site where user can post an entry.

The objective is: To have the Homepage display all the blog post in a list and details of any one blog post next to it when the Homepage first loads. When the user clicks on any item from the list the details of which will replace the default blog details. Basically how Indeed displays the job posts.

Method: I make 2 Axios calls one to get all the data and the other to get data by id. The data from getAllData is displayed in a list on HomePage The data is passed as props to HomePageListItems which are wrapped in <Link to= { /${idx} }/>

I use the useParams to get the id and make getDataId call in DataById.

So, HomePage has to child components HomePageListItems and DataById Issue is:

  1. Function getDataById in does not work when Homepage is first loaded. It only works when route is "localhost/:id" which is "localhost:3000/ae86140b-7ae6-457-826c-5bd324b8cb3"

  2. Because I want one blog already displayed when the first loads: How I do have this getDatabyId function run with a preset id where the id changes when the user clicks on a list item?

The code is:

import React, { useState, useEffect, usePrevious } from "react";
import { Link, useParams } from "react-router-dom";
import Axios from "axios";
import HomePageListItems from "./homePageListItems";
import DataById from "./dataById";

export default function HomePage(props){
  <DataById/>
    const [getAllData, setGetAllData] = useState()
    const getData =async () => {
      await  Axios.get("http://localhost:5000/get").then((response)=>{
        setGetAllData(response.data)
        })
        .catch((error)=>{console.log(error)})
    }
    useEffect(()=>{
        getData();
      },[])
    return(
        <section>
          <Link to = "/postJournal">Post Journal Entry</Link>
            {getAllData&&getAllData.map((item)=>{
                return(
                    <HomePageListItems
                    key={item.id}
                    idx={item.id}
                    name={item.name}
                    title={item.title}
                    journalEntry={item.journalEntry}
                    date={item.date}
                    file={item.file}
                    />
                )
            })
            
        }
         {usePrevious}
        <DataById/>
        </section>
        
    )
}

--

    import React, { useState, useEffect, usePrevious } from "react";
    import { useParams } from "react-router-dom";
    import Axios from "axios";
    
    export default function DataById(props){
      console.log("DataProps",props)
      const [axiosGetData, setAxiosGetData] = useState([])
      const {id} = useParams()
      const getDataById =async () => {
            await  Axios.get(`http://localhost:5000/${id}`).then((response)=>{
              setAxiosGetData(response.data[0])
                  console.log("Data",response.data[0])
              })
              .catch((error)=>{console.log(error)})
          }
          useEffect(()=>{
            getDataById("35b48be0-0ab8-4409-a5eb-a0c4dbd0a4b3");
          },[id])
    
        return(
          <>
          <p> DataByID</p>
            name:{axiosGetData.name}
            Date:{axiosGetData.date}
            Journal:{axiosGetData.journalEntry}
            {usePrevious}
          </>
        
        )
    
    }  

--

    import React, { useState, useEffect, usePrevious} from "react";
    import { Link} from "react-router-dom";
    
    export default function HomePageListItems(props){
        let {name,title,journalEntry,date,file,idx}=props
        return(
            <main className= "homepage">
               <Link to={`/${idx}`} >
                <section className="homepage__listContainer">
                    <ul className = "homepage__list">
                        <li className="homepage__listItemWrapper">
                            <div className ="homepage__listItem">
                                <div className = "homepage__listItemImgWrapper">
                                    <img className = "homepage__listItemImg" alt="" src={file}/>
                                </div>
                                <h3 className= "homepage__listItemTitle">Title:{title}</h3>
                                <p className = "homepage__listItemAuthor">Name:{name}</p>
                                <p className = "homepage__listItemDescription">Description:{journalEntry}</p>
                                <p className = "homepage__listItemDate">Posted Date:{date}</p>
                                <p>Key:{idx}</p>
                            </div>
                        </li>
                    </ul>
                </section>
                 </Link>
                {usePrevious}  
            </main>
          
        )
    }

--
import React from "react";
import "./style/App.css";
import ReactDOM from 'react-dom';
import { BrowserRouter, Switch, Router, Route } from "react-router-dom";
import HomePage from "./components/homePage"
import PostJournalEntry from "./components/postJournalEntry"
import DataByIDfrom "./components/dataById"


function App() {
  return (
    <div className="app">
      <BrowserRouter>
      <Switch>
      <Route path="/:id" exact component = {HomePage}/>
      <Route path="/:id" exact component = {DataByID}/>
      <Route path="/postJournal" exact component = {PostJournalEntry}></Route>
      <Route path="/" exact component = {HomePage}/>
      </Switch>
      </BrowserRouter>
    </div>
  );
}

export default App;

Thanks in advance guys! Any help is appriciated.

It's because getDataById doesn't accept any arguments, it always uses the URL id (useParams) for the axios get call, passing it an id in the useEffect won't do anything. You need to add a parameter to the function and then add some logic so it knows whether to use a passed in value or the URL id value. You could try something like this:

      const getDataById = async (startupId = null) => {
            await  Axios.get(`http://localhost:5000/${startupId ? startupId : id}`).then((response)=>{
              setAxiosGetData(response.data[0])
                  console.log("Data",response.data[0])
              })
              .catch((error)=>{console.log(error)})
          }

This way if you pass getDataById an argument it will use that value for the axios call, otherwise it will try to use the id value from useParams

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