简体   繁体   中英

React: Update one state variable using another state variable

What I am trying to achieve:

Retrieve book -> take book.chapterIds[0] to update currentChapter -> take currentChapter to update chapters

I am using one state variable(Book) to set another state variable(chapters), like so:

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]);

For second useEffect, I end up getting: Uncaught TypeError: book.chapterIds is undefined

Here is what I tried:

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

which kinda works, but I still ends up triggering:

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

where both book and currentChapter is undefined

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]);

Also, I get book.chapterIds as undefined on using it inside Book component return()

What am I doing wrong?

Try to set all initial states as null:

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

Then your 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]);

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