React:使用另一个状态变量更新一个状态变量

React: Update one state variable using another state variable

我想要达到的目标:

检索book->取book.chapterIds[0]更新currentChapter->取currentChapter更新chapters

我正在使用一个状态变量(书籍)来设置另一个状态变量(章节),如下所示:

useEffect(() => {
  getBook(match.params.id);
  // eslint-disable-next-line
 }, []);

useEffect(() => {
 setCurrentChapter(book.chapterIds[0]);
 // eslint-disable-next-line
}, [book]);

useEffect(() => {
  getChapter(currentChapter);
  // eslint-disable-next-line
 }, [currentChapter]);

对于第二次useEffect,我最终得到:Uncaught TypeError: book.chapterIds is undefined

这是我尝试过的:

useEffect(() => {
 if (Object.keys(book).length !== 0) {
 setCurrentChapter(book.chapterIds[0]);
}
 // eslint-disable-next-line
}, [book]);

哪个有点用,但我还是触发了:

useEffect(() => {
 getChapter(currentChapter);
 // eslint-disable-next-line
}, [currentChapter]);

其中 book 和 currentChapter 都未定义

App.js

const [book, setBook] = useState({});
const [chapters, setChapters] = useState({});
const [currentChapter, setCurrentChapter] = useState();   
const [loading, setLoading] = useState(false);

const getBook = async (id) => {
 setLoading(true);
 const res = await axios.get(`<someurl><with id>`);
 console.log(res.data);
 setBook(res.data.book);
 setLoading(false);
};

const getChapter = async (chapterId) => {
  if (chapters[chapterId] === undefined) {
    console.log(`<someurl><with id & chapterId>`);
    setLoading(true);
    const res = await axios.get(
     `<someurl><with id & chapterId>`
    );
    setLoading(false);
    console.log(res.data);
    setChapters({
     ...chapters,
     [chapterId]: res.data.chapter,
   });
  }
 };

Book.js

 useEffect(() => {
  getBook(match.params.id);
  // eslint-disable-next-line
 }, []);

 useEffect(() => {
  if (Object.keys(book).length !== 0) {
   setCurrentChapter(book.chapterIds[0]);
  }
  // eslint-disable-next-line
  }, [book]);

 useEffect(() => {
  getChapter(currentChapter);
  // eslint-disable-next-line
 }, [currentChapter]);

此外,在 Book 组件中使用它时我得到 book.chapterIds 未定义return()

我做错了什么?

尝试将所有初始状态设置为空:

const [book, setBook] = useState(null);
const [chapters, setChapters] = useState(null);
const [currentChapter, setCurrentChapter] = useState(null); 

然后你的 useEffects:

 useEffect(() => {
  getBook(match.params.id);
  // eslint-disable-next-line
 }, []);

useEffect(() => {
 if(book && book.chapterIds?.length > 0)
     setCurrentChapter(book.chapterIds[0]);
 // eslint-disable-next-line
}, [book]);

useEffect(() => {
  if(currentChapter)
    getChapter(currentChapter);
  // eslint-disable-next-line
 }, [currentChapter]);