728x90

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

발생 Error

React에서 다음 Source Code를 실행할 경우,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React from "react";
import { Navigate } from "react-router-dom";
 
const TempComp = (props) => {
    const tempHandler = () => {
        Navigate("/TempPage");
    };
    return (
        <div>
            <button onClick={tempHandler}>
                <span>Button</span>
            </button>
        </div>
    );
};
 
export default TempComp;
 
 
 

🚨 다음과 같은 오류 발생

Invalid hook call.

Hooks can only be called inside of the body of a function component.

This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

 

 

발생 원인

⭐ Navigate Hook은 컴포넌트의 함수 본문 내(return 안)에서 사용해야하지만, 함수 본문 외(return 밖)에서 실행

 

 

해결 방법

onClick 함수에서 tempHandler를 함수형으로 직접 선언

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React from "react";
import { Navigate } from "react-router-dom";
 
const TempComp = (props) => {
    const TempHandler = () => {
        Navigate("/TempPage");
    };
    return (
        <div>
            <button onClick={() => {TempHandler();}}>
                <span>Button</span>
            </button>
        </div>
    );
};
 
export default TempComp;
 
 
 

 

728x90
728x90

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

발생 Error

React에서 다음 Source Code를 실행할 경우,

1
2
3
4
5
6
7
8
9
10
  function addMovieHandler(movie) {
    const response = await fetch('https://react-http-e9810-default-rtdb.firebaseio.com/movies.json', {
      method: 'POSt',
      body: JSON.stringify(movie),
      headers: {
        'Content-Type''application/json'
      }
    });
  }
 
 
 

🚨 다음과 같은 오류 발생

'await' expressions are only allowed within async functions and at the top levels of modules.

 

 

발생 원인

'await': 프로미스가 해결(resolve)될 때까지 기다리는 역할 = 데이터를 전달받을 때까지 기다리는 역할
🚨 비동기 함수(async function) 안에서만 사용되어야 하며, 함수 외부에서 사용하려면 비동기 함수를 호출해야함

 

 

해결 방법

비동기 함수 선언: async function

1
2
3
4
5
6
7
8
9
10
  async function addMovieHandler(movie) {
    const response = await fetch('https://react-http-e9810-default-rtdb.firebaseio.com/movies.json', {
      method: 'POSt',
      body: JSON.stringify(movie),
      headers: {
        'Content-Type''application/json'
      }
    });
  }
 
 
 

 

728x90
728x90

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

발생 Error

React에서 다음 Source Code를 실행할 경우,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { useDispatch } from "react-redux";
import classes from "./CartItem.module.css";
import { cartActions } from "../../store/cart-slice";
 
const CartItem = (props) => {
  const dispatch = useDispatch();
  const { title, quantity, id, total, price } = props.item;
  
  const removeItemHandler = () => {
    dispatch(cartActions.removeItemToCart(id));
  };
  const addItemHandler = () => {
    dispatch(cartActions.addItemToCart(id, title, price));
  };
 
  return (
    <li className={classes.item}>
      <header>
        <h3>{title}</h3>
        <div className={classes.price}>
          ${total.toFixed(2)}{" "}
          <span className={classes.itemprice}>(${price.toFixed(2)}/item)</span>
        </div>
      </header>
      <div className={classes.details}>
        <div className={classes.quantity}>
          x <span>{quantity}</span>
        </div>
        <div className={classes.actions}>
          <button onClick={removeItemHandler}>-</button>
          <button onClick={addItemHandler}>+</button>
        </div>
      </div>
    </li>
  );
};
 
export default CartItem;
 
 
 

🚨 다음과 같은 오류 발생

TypeError: Cannot read properties of undefined (reading 'toFixed')

 

 

발생 원인

addItemToCart로 전달한 action.payload값이 객체가 아닌 개별값으로 전달

action.payload = id = newItem이 되어 state 업데이트가 제대로 일어나지 않음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { createSlice } from "@reduxjs/toolkit";
 
const cartSlice = createSlice({
  name"cart",
  initialState: {
    items: [],
    totalQuantity: 0,
  },
  reducers: {
    addItemToCart(state, action) {
      const newItem = action.payload;
      const existingItem = state.items.find((item) => item.id === newItem.id);
      state.totalQuantity++;
      if (!existingItem) {
        state.items.push({
          id: newItem.id,
          price: newItem.price,
          quantity: 1,
          totalPrice: newItem.price,
          name: newItem.title,
        });
      } else {
        existingItem.quantity++;
        existingItem.totalPrice = existingItem.totalPrice + newItem.price;
      }
    },
    removeItemToCart(state, action) {
      const id = action.payload;
      const existingItem = state.items.find((item) => item.id === id);
      state.totalQuantity--;
      if (existingItem.quantity === 1) {
        state.items = state.items.filter((item) => item.id !== id);
      } else {
        existingItem.quantity--;
        existingItem.totalPrice = existingItem.totalPrice - existingItem.price;
      }
    },
  },
});
 
export const cartActions = cartSlice.actions;
 
export default cartSlice;
 
 

 

 

해결 방법

{id, title, price}를 객체로 묶어서 전달

action.payload = {id, title, price} = newItem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { useDispatch } from "react-redux";
import classes from "./CartItem.module.css";
import { cartActions } from "../../store/cart-slice";
 
const CartItem = (props) => {
  const dispatch = useDispatch();
  const { title, quantity, id, total, price } = props.item;
  
  const removeItemHandler = () => {
    dispatch(cartActions.removeItemToCart(id));
  };
  const addItemHandler = () => {
    dispatch(cartActions.addItemToCart({id, title, price}));
  };
 
  return (
    <li className={classes.item}>
      <header>
        <h3>{title}</h3>
        <div className={classes.price}>
          ${total.toFixed(2)}{" "}
          <span className={classes.itemprice}>(${price.toFixed(2)}/item)</span>
        </div>
      </header>
      <div className={classes.details}>
        <div className={classes.quantity}>
          x <span>{quantity}</span>
        </div>
        <div className={classes.actions}>
          <button onClick={removeItemHandler}>-</button>
          <button onClick={addItemHandler}>+</button>
        </div>
      </div>
    </li>
  );
};
 
export default CartItem;
 
 
 

 

 

참고 자료

⭐ Web Browser에서 Debugging하는 법

 

728x90
728x90

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

발생 Error

React에서 다음 Source Code를 실행할 경우,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { createSlice } from '@reduxjs/toolkit';
import React from 'react';
 
const initialState = {count: 0};
 
const countSlice = createSlice({
    name'count',
    initialState,
    reducers: {
        increment(state) {state.count + 1},
    },
 
});
 
export default countSlice;
 
 
 

🚨 다음과 같은 오류 발생

Expected an assignment or function call and instead saw an expression

 

 

발생 원인

state.count 값을 변화시키기 위한 표현식이 잘못 기재되어있음

state.count + 1은 state.count 값을 변화시키기는 것이 아니라 반환된 값에 1을 더하는 표현식

 

 

해결 방법

state.count + 1을 변화시키는 수식으로 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { createSlice } from '@reduxjs/toolkit';
import React from 'react';
 
const initialState = {count: 0};
 
const countSlice = createSlice({
    name'count',
    initialState,
    reducers: {
        increment(state) {state.count += 1},
    },
 
});
 
export default countSlice;
 
 
 

 

728x90
728x90

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

발생 Error

React에서 다음 Source Code를 실행할 경우,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
 
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
 
reportWebVitals();
 
 
 

🚨 다음과 같은 오류 발생

could not find react-redux context value;

please ensure the component is wrapped in a <Provider>

 

 

발생 원인

Redux store를 전역으로 사용하기 위한 설정, store prop 공유가 기재되어있지 않음

 

 

해결 방법

Redux 스토어를 전역적으로 제공하기 위해 Provider 선언 및 store prop 전달

 - Provider: 하위 컴포넌트인 App 컴포넌트와 그 아래에 있는 모든 컴포넌트에 Redux 스토어를 제공
 - store: Redux 스토어 객체, Provider 컴포넌트의 store prop으로 전달되어 모든 컴포넌트에 공유됨

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
 
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './store/index';
 
import './index.css';
 
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);
 
reportWebVitals();
 
 
 

 

728x90