各位大大您好!最近遇到一個棘手的問題想向各位請教~
當我進去某個指定人物的頁面後,會利用useEffect來執行第一次的render,從資料庫抓取該角色的詳細資料,並將其存入到useState的array中,並將其資料render至該頁面中,但遇到了一個問題,進去頁面時會質性第一次render,在執行useEffect(也就是抓取該人物的詳細資料),但第一次render時,還未抓取到該人物的資料,造成undefined,想請問該怎麼辦QQ
ChampionDetails.js :
const ChampionsDetail = () => {
  const location = useLocation();
  const history = useHistory();
  const { name, id } = useParams();  // name:Iron man ; id:1
  const [champDetails, setChampDetails] = useState({ clothes: {}, skills: {}});
  const championInfo = location.state;
  /* 畫面初始值 */
  useEffect(() => {
    fetchChampionDetail();
    document.title = `${name}'s Detail`;
  },[]);
  /* function fetchDetail 抓取該人物的詳細資料 */
  const fetchChampionDetail = async () => {
    const result = await Axios.get(
      `http://localhost:3001/champions_detail/id=${id}&${name}`
    );
    Axios.all([result])
      .then(
        Axios.spread((result) => {
          setChampDetails({
            clothes: result.data[0],
            skills: result.data[1]
          });
        })
    )
      .catch((errors) => {
        console.error(errors);
      });    
  };
  /* function handleBackClick */
  const handleBackClick = () => {
    history.goBack();
  };
  return (
    <div>
      <h1>
        Champion {name}'s Detail Pages
      </h1>
      <button
        onClick={() => {
          handleBackClick();
        }}
      >Back to the Champion Page</button>
          <p>{champDetials.clothes[0].clothes_name}</p>
    </div>
  );
}
export default ChampionsDetail;
{champDetials.clothes[0].clothes_name}在這裡出錯了
先謝謝各位的幫忙!!,仍在學習中,任何指教都願意聆聽~
const ChampionsDetail = () => {
  const location = useLocation();
  const history = useHistory();
  const { name, id } = useParams();
  
  // 在獲得後端資料前,先將state值設定為一個可以讓你辨識「還沒獲得後端資料」的值
  const [champDetails, setChampDetails] = useState(undefined);
  
 
  const championInfo = location.state;
  useEffect(() => {
    fetchChampionDetail();
    document.title = `${name}'s Detail`;
  },[]);
  const fetchChampionDetail = async () => {
    const result = await Axios.get(
      `http://localhost:3001/champions_detail/id=${id}&${name}`
    );
    Axios.all([result])
      .then(
        Axios.spread((result) => {
          setChampDetails({
            clothes: result.data[0],
            skills: result.data[1]
          });
        })
    )
      .catch((errors) => {
        console.error(errors);
      });    
  };
  const handleBackClick = () => {
    history.goBack();
  };
  
  /* 
  在JS中,「 A && B 」 代表的是當A為true,則回傳B
  下面<p></p>中的JS寫法你也可以寫成:
  if(champDetials !== undefined)
      return champDetials.clothes[0].clothes_name;
  */
  
  return (
    <div>
      <h1>
        Champion {name}'s Detail Pages
      </h1>
      <button
        onClick={() => {
          handleBackClick();
        }}
      >Back to the Champion Page</button>
          <p>{champDetials && champDetials.clothes[0].clothes_name}</p>
    </div>
  );
}
export default ChampionsDetail;
喔喔!!所以useState是可以先定義為 undefined!!,我在提問前查了網路上很多資料,有些是說可以再用一個useEffect去來看是否更新值,不知道有沒有這種寫法QAQ 另外您的方法,成功讓我render成功了!!!我等等再run一次您跟我說的概念~~謝謝您!
對了,你detail拼錯了XD
因為不只有一個值要render,所以如果要的話 是全部都要用您說的A && B  才能在整個頁面使用嗎QAQ
有我看到了哈哈 我剛剛測試發現了~~嘿嘿
看你的資料是不是從後端拿的啊~ 一般而言,我們會把需要同一份資料的頁面拆出來成一個component,這樣你只要寫一次下面的code就能解決所有問題囉
資料 && <頁面元件 />
那這樣像您說的 我把它拆成Detail.js 我要把render的畫面放進去是嗎? 不然我不太懂您說的這個方法QQ
類似這樣的概念
  return (
    <div>
      <h1>
        Champion {name}'s Detail Pages
      </h1>
      <button
        onClick={() => {
          handleBackClick();
        }}
      >Back to the Champion Page</button>
      {champDetails && <Detail data={champDetails}>}
    </div>
  );
}
另外有一種狀況是當你需要call多次api向後端拿不同資料才能呈現單一頁面,這時會比較複雜,我所知道的有兩種做法:
Promise.all()等每隻api都傳回來再初始化,但這個比較複雜也比較容易出錯那像這樣呢
ChampionDetail.js
 return (
    <div className="detailContainer">
      {champDetails && <Detail data={champDetails}>}
    </div>
  );
}
Detail.js: (ChampionDetails.js會傳送一個props(champDetails)過來)
const Detail = ({champDetails}) => {
return (
    <div>
    <h1>{champDetails.clothes[0].clothes_name}</h1>
    <p>{champDetails.skills[0].skill_name}</p>
    </div>
)
}
這樣對嗎~~?
理論上是對的,就看執行結果符不符合你的期望
Andy Chang
下面那個方法,未來我會試做看看!! 另外題外話,想問有方法將資料的資料做成API嗎XD 現在剛接觸這個領域中~抱歉問題很多
好了解了 我試做看看!!! 總之謝謝您!!!
將資料的資料做成API
不懂, 你可能要再描述清楚一點
應該說如何做屬於自己網頁的API,畢竟我的資料現在只存在我的MYSQL中,未來若有相關網頁需要,就可以直接抓API了,而不是像現在去跟資料庫撈哈哈
Andy Chang了解了 感謝您的解釋~~非常有幫助,Firebase我有聽過,未來我會研究看看的 謝謝~