0

currently I am working on a project and find myself in a bothersome situation. Is it normal for the components to load before useEffect?

On my page I want to implement pagination on sidebar. I have state which will determine current page and that state which is number will be an index which will take nested array and show the content. However data is an array without nested arrays and firstly I should convert that array into array with nested ones. Because that, I want to run that inside side effect because it should only be done at initial loading. Now I am trying with hardcoded values and later will set dynamic ones.

The problem now is that useEffect doesn't run first and the rest of code actually executes itself before useEffect and I got errors like "MenuList.js:173 Uncaught TypeError: DUMMY_FOOD[0].map is not a function" and ect. I know that my array is not in right format hence if I log without this [0] it works.

What is problem?

Code:

const MenuList = () => { const navigate = useNavigate(); const location = useLocation(); const params = useParams(); const [page, setPate] = useState(0); useEffect(() => { const pages = Math.ceil(DUMMY_FOOD.length / 5); const arr = []; let helpArr = []; let c = 0; for (let i = 0; i < pages; i++) { for (let j = c; j < c + 5; j++) { console.log("picapicapiac"); helpArr.push(DUMMY_FOOD[j]); } c += 5; arr.push(helpArr); helpArr = []; } console.log(arr); DUMMY_FOOD = arr; }, []); console.log(DUMMY_FOOD); const queryPrams = new URLSearchParams(location.search); const sort = queryPrams.get("sort"); const onNextPageHandler = () => {}; const onPreviousPageHandler = () => {}; const onSortPageHandler = () => { navigate(`/menu/${params.foodId}/?sort=${sort === "asc" ? "desc" : "asc"}`); sort === "asc" ? (DUMMY_FOOD = DUMMY_FOOD.sort((a, b) => a.foodPrice - b.foodPrice)) : (DUMMY_FOOD = DUMMY_FOOD.sort((a, b) => b.foodPrice - a.foodPrice)); }; return ( <Fragment> <div className={classes["menu-list"]}> {DUMMY_FOOD.map((foodObj) => ( <MenuItem key={foodObj.id} foodObj={foodObj} /> ))} </div> <div className={classes["menu-list__buttons"]}> <Button type="button" onClick={onPreviousPageHandler}> Page 2 </Button> <Button type="button" onClick={onSortPageHandler}> {sort === "asc" ? `Descending &#8593` : `Ascending &#8595`} </Button> <Button type="button" onClick={onNextPageHandler}> Page 3 </Button> </div> </Fragment> ); }; export default MenuList; 
1
  • Note, this code works right now because I do not use DUMMY_FOOD[0] Commented Jun 1, 2022 at 12:40

3 Answers 3

1

This is expected behavior, useEffect is not a synchronous function.

What you want to do is make sure your arrays have items in them and are not null/undefined, to make sure renders don't break.

From React's docs:

Unlike componentDidMount or componentDidUpdate, effects scheduled with useEffect don’t block the browser from updating the screen. This makes your app feel more responsive. The majority of effects don’t need to happen synchronously.

Comments

0

Using your Dummy_food variable below.. not sure where it's coming from but I kept it in the code.

useEffect(() => { const pages = Math.ceil(DUMMY_FOOD.length / 5); const arr = []; let helpArr = []; let c = 0; for (let i = 0; i < pages; i++) { for (let j = c; j < c + 5; j++) { console.log("picapicapiac"); helpArr.push(DUMMY_FOOD[j]); } c += 5; arr.push(helpArr); helpArr = []; } console.log(arr); DUMMY_FOOD = arr; }, []); 

Have a portion that displays your links. This will not error out if there are no links at render.

const RenderPagination= () => { return DUMMY_FOOD.map((f, index) => { return ( <li>{f}</li> ); }); }; 

Then where your displaying your items...

{RenderPagination()} 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.