各位好,小弟目前使用react+axios作API串接,遇到一些問題,我目前使用axios請求資料回來後放進dataSG參數,在Axios.spread裡面dataSG顯示返回的資料,但是放進組件的{...dataSG}卻是初始值沒有被更動的,好像只要離開fetchStationAll(),dataSG就會是初始值,想請較各位大大這是什麼原因? 謝謝~
import React, { useEffect, useState } from 'react'
import styled from 'styled-components'
import Axios from 'axios'
import { GetStation as SG, StationPosition as SP, Stationimmediate as SI } from '../api/apis'
import cookies from 'react-cookies'
import StationInfo from './ProjectData/StationInfo'
import StationPosition from './ProjectData/StationPosition'
import StationImmediate from './ProjectData/StationImmediate'
const ProjectData = props => {
const { pjid, pjn } = props.match.params;
const navList = ['AAA', 'BBB', 'CCC']
let dataSG = ""
let dataSP = ""
let dataSI = ""
const [pageCurrent, setPC] = useState("AAA");
const apiParams = {
params: {
PJid: pjid
},
headers: {
Authorization: `Bearer ${cookies.load('react-token').Token}`
}
}
const resSG = Axios.get(SG, apiParams)
const resSP = Axios.get(SP, apiParams)
const resSI = Axios.get(SI, apiParams)
useEffect(() => {
const fetchStationAll = async () => {
await Axios.all([resSG, resSI, resSP]).then(
Axios.spread((...res) => {
dataSG = res[0].data.Payload
dataSI = res[1].data.Payload
dataSP = res[2].data.Payload
console.log(dataSG)//有返回資料
})
).catch(err => {
console.log(err)
})
}
fetchStationAll()
}, [pjid]);
const changePage = (e) => {
}
return (
<React.Fragment>
<Container>
<div>
<h3>{pjn}</h3>
</div>
<PageList>
{navList.map(el => <PageText key={el} onClick={() => changePage(el)}>{el}</PageText>)}
</PageList>
<div>
<StationInfo {...dataSG} />
<StationImmediate {...dataSI} />
<StationPosition {...dataSP} />
</div>
</Container>
</React.Fragment>
);
}
const Container = styled.div({
minHeight: 'calc(100vh - 54px)',
padding: '1rem'
})
const PageList = styled.ul({
display: 'flex',
listStyle: 'none',
padding: '0',
fontFamily: '微軟正黑體',
fontWeight: 'bolder'
})
const PageText = styled.li`
&:hover{
cursor:pointer;
color:blue
}
&:nth-child(2):after,&:nth-child(2):before{
content:"/";
margin:0px 5px;
}
`
export default ProjectData;
let dataSG = ""
let dataSP = ""
let dataSI = ""
不能存在常數裡面,應該要存在state
const [data, setData] = useState() ;
然後再 useEffect
裡面,資料取完之後再去 setData({SG:dataSG, ...})
資料要怎存自己定義囉,render
的時候要取用則直接呼叫 data
即可
補充:會造成這原因,主要是因為 react
每次 render
資料異動都會再 render
等於說會再執行一次你設定的整個 component function
,因此宣告常數等於他每次都會宣告一次,並且把裡面設定為空值。
這算是我目前學下來的理解..有錯還請各位大大幫忙糾正
Han大大,我後來改成這樣
let dataSG = ""
let dataSI = ""
let dataSP = ""
const [response, setResponse] = useState()
const [pageCurrent, setPC] = useState("測站更新狀態");
const apiParams = {
params: {
PJid: pjid
},
headers: {
Authorization: `Bearer ${cookies.load('react-token').Token}`
}
}
const resSG = Axios.get(SG, apiParams)
const resSP = Axios.get(SP, apiParams)
const resSI = Axios.get(SI, apiParams)
useEffect(() => {
const fetchStationAll = async () => {
await Axios.all([resSG, resSI, resSP]).then(
Axios.spread((...res) => {
dataSG = res[0].data.Payload
dataSI = res[1].data.Payload
dataSP = res[2].data.Payload
setResponse({ SG: dataSG, SI: dataSI, SP: dataSP })
})
).catch(err => {
console.log(err)
})
}
fetchStationAll()
console.log(response);
}, [pjid]);
資料的確有更新到了~但是變成我的response不是最新的資料,都會是上一次呼叫API結果的資料,請問這是什麼原因造成的嗎?
請問你這 api 是要在何種情況下驅動更新呢?
如果照你目前這樣寫
只有在 pjid
有更動的時候才會進行 useEffect
裡面的動作
進而驅動再次進行 fetchStationAll()
的動作
我目前是要頁面進來時,pjid就要先執行一次了,但是目前一進到這個頁面,剛剛看到response是undefined,後面再點一次才會有值,然後值是剛進來的pjid,所以導致剛剛的問題
const [response, setResponse] = useState()
可以在 useState({})
塞預設值,避免使用者看到 undefined
這樣塞是為了避免,api在pending期間的使用者等待畫面處理
我設了預設值,但是一進頁面response卻是預設值,沒有更新資料,第二次進入頁面時,pjid為第一次進來時的值,第三次為第二次的pjid...依此類推,請問要怎麼讓它進來的時候便會渲染第一次的值?
應該是因為,你的 fetchStationAll
這個裡面 Promise
的問題,你可以檢查一下這部分,自己稍微模擬了一,不知道有沒有符合你的情境,模擬畫面
目前有達到我的需求了~ 感謝你的幫忙,我可能還要再熟悉一下HooksXD