• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

useHistory를 이용한 push에서 typeError가 납니다ㅠㅠ

21.07.07 14:36 작성 조회수 185

1

강사님이 해주신대로 작성했는데... typeError가 나네요ㅠㅠ

TypeError: Cannot read property 'push' of undefined

라고 나옵니다ㅠㅠ history.push 이부분이 잘못됐다는 의미같은데 어디가 틀렸는지 모르겠네요. 코드첨부합니다.

import "antd/dist/antd.css";
import "./App.css";
import MainPageComponent from "./main";
import "./index.css";
import {
  Switch,
  Route,
  BrowserRouter,
  Link,
  useHistory,
} from "react-router-dom";
import UploadPage from "./upload";
import ProductPage from "./product";
import { Button } from "antd";
import { DownloadOutlined } from "@ant-design/icons";

function App() {
  const history = useHistory();
  return (
    <BrowserRouter>
      <div id="header">
        <div id="header-area">
          <Link to="/">
            <img src="/images/icons/logo.png" />
          </Link>
          <Button
            size="large"
            onClick={function () {
              history.push("/upload");
            }}
            icon={<DownloadOutlined />}
          >
            상품 업로드
          </Button>
        </div>
      </div>
      <div id="body">
        <Switch>
          <Route exact={true} path="/">
            <MainPageComponent />
          </Route>
          <Route exact={true} path="/products/:id">
            <ProductPage />
          </Route>
          <Route exact={true} path="/upload">
            <UploadPage />
          </Route>
        </Switch>
      </div>
      <div id="footer"></div>
    </BrowserRouter>
  );
}

export default App;

답변 3

·

답변을 작성해보세요.

0

토빌님의 프로필

토빌

질문자

2021.07.11

아래와 같이 뜹니다!

url이 http://localhost:3000/upload 이렇게 바뀌는데 이동이 안되어서 새로고침을 해야 upload 화면이 켜지네요ㅠㅠ

[HMR] Waiting for update signal from WDS...

webpackHotDevClient.js:138 src\App.js

  Line 24:13:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text

src\main\index.js

  Line 43:17:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text

  Line 61:19:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text

  Line 71:23:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text

src\product\index.js

  Line 26:6:  React Hook useEffect has a missing dependency: 'getProduct'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

  Line 47:9:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images      jsx-a11y/alt-text

  Line 50:9:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images      jsx-a11y/alt-text

src\upload\index.js

  Line 63:15:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text

  Line 66:17:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text

printWarnings @ webpackHotDevClient.js:138

index.js:1 Warning: Each child in a list should have a unique "key" prop.

Check the render method of `MainPage`. See https://reactjs.org/link/warning-keys for more information.

    at div

    at MainPage (http://localhost:3000/static/js/main.chunk.js:893:80)

    at Route (http://localhost:3000/static/js/vendors~main.chunk.js:185431:29)

    at Switch (http://localhost:3000/static/js/vendors~main.chunk.js:185633:29)

    at div

    at Router (http://localhost:3000/static/js/vendors~main.chunk.js:185066:30)

    at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:184686:35)

    at App (http://localhost:3000/static/js/main.chunk.js:248:86)

    at Router (http://localhost:3000/static/js/vendors~main.chunk.js:185066:30)

    at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:184686:35)

App.js에 BrowserRotuer는 지우신거 맞죠?

Github 소스코드 공유해주시면 제가 좀이따 확인해볼게요~!

토빌님의 프로필

토빌

질문자

2021.07.11

아아 App.js에 있던걸 안지웠네요ㅠㅠ 지우고 div 태그 넣었더니 됩니다!

정말 감사합니다ㅠㅠ

수업 잘 들었어용

다행입니다! 화이팅 ~!!!

0

토빌님의 프로필

토빌

질문자

2021.07.08

여기 있습니다~

import { Form, Divider, Input, InputNumber, Button } from "antd";
import "./index.css";

function UploadPage() {
  const onSubmit = (values) => {
    console.log(values);
  };
  return (
    <div id="upload-container">
      <Form name="상품 업로드" onFinish={onSubmit}>
        <Form.Item
          name="upload"
          label={<div className="upload-label">상품 사진</div>}
        >
          <div id="upload-img-placeholder">
            <img src="/images/icons/camera.png" />
            <span>이미지를 업로드 해주세요.</span>
          </div>
        </Form.Item>
        <Divider />
        <Form.Item
          label={<div className="upload-label">판매자 명</div>}
          name="seller"
          rules={[{ required: true, message: "판매자 이름을 입력해주세요." }]}
        >
          <Input
            className="upload-name"
            size="large"
            placeholder="이름을 입력해주세요."
          />
        </Form.Item>
        <Divider />
        <Form.Item
          name="name"
          label={<div className="upload-label">상품 이름</div>}
          rules={[{ required: true, message: "상품 이름을 입력해주세요." }]}
        >
          <Input
            className="upload-name"
            size="large"
            placeholder="상품 이름을 입력해 주세요."
          />
        </Form.Item>
        <Divider />
        <Form.Item
          name="price"
          label={<div className="upload-label">상품 가격</div>}
          rules={[{ required: true, message: "상품 가격을 입력해주세요." }]}
        >
          <InputNumber defaultValue={0} className="upload-price" size="large" />
        </Form.Item>
        <Divider />
        <Form.Item
          name="description"
          label={<div className="upload-label">상품 소개</div>}
          rules={[{ required: true, message: "상품 소개를 입력해주세요" }]}
        >
          <Input.TextArea
            size="large"
            id="product-description"
            showCount
            maxLength={300}
            placeholder="상품 소개를 적어주세요."
          />
        </Form.Item>
        <Form.Item>
          <Button id="submit-button" size="large" htmlType="submit">
            문제 등록하기
          </Button>
        </Form.Item>
      </Form>
    </div>
  );
}

export default UploadPage;
import { useParams } from "react-router-dom";
import axios from "axios";
import { useEffect, useState } from "react";
import "./index.css";

function ProductPage() {
  const [product, setProduct] = useState(null);
  const { id } = useParams();
  useEffect(function () {
    axios
      .get(
        `https://c2e78e79-909f-425e-9419-cef6efbaefa3.mock.pstmn.io/products/${id}`
      )
      .then(function (result) {
        setProduct(result.data);
      })
      .catch(function (error) {
        console.error(error);
      });
  }, []);

  if (product === null) {
    return <h1>상품정보를 받고 있습니다...</h1>;
  }

  return (
    <div>
      <div id="image-box">
        <img src={"/" + product.imageUrl} />
      </div>
      <div id="profile-box">
        <img src="/images/icons/avatar.png" />
        <span>{product.seller}</span>
      </div>
      <div id="contents-box">
        <div id="name">{product.name}</div>
        <div id="price">{product.price}원</div>
        <div id="createdAt">2020년 7월 7일</div>
        <div id="description">{product.description}</div>
      </div>
    </div>
  );
}
export default ProductPage;
import { useParams } from "react-router-dom";
import axios from "axios";
import { useEffect, useState } from "react";
import "./index.css";

function ProductPage() {
  const [product, setProduct] = useState(null);
  const { id } = useParams();
  useEffect(function () {
    axios
      .get(
        `https://c2e78e79-909f-425e-9419-cef6efbaefa3.mock.pstmn.io/products/${id}`
      )
      .then(function (result) {
        setProduct(result.data);
      })
      .catch(function (error) {
        console.error(error);
      });
  }, []);

  if (product === null) {
    return <h1>상품정보를 받고 있습니다...</h1>;
  }

  return (
    <div>
      <div id="image-box">
        <img src={"/" + product.imageUrl} />
      </div>
      <div id="profile-box">
        <img src="/images/icons/avatar.png" />
        <span>{product.seller}</span>
      </div>
      <div id="contents-box">
        <div id="name">{product.name}</div>
        <div id="price">{product.price}원</div>
        <div id="createdAt">2020년 7월 7일</div>
        <div id="description">{product.description}</div>
      </div>
    </div>
  );
}
export default ProductPage;

엇 각 페이지의 index.js가 아닌 가장 상위인 src/index.js를 이야기하는 거 였어요!

BrowserRouter를 app.js의 상위인 src/index.js로 두시고 해보시겠어요~?
현재는 BrowserRouter를 app.js에서 Wrapping하고 있습니다.


https://github.com/yansfil/grab-market-client/blob/main/src/index.js

토빌님의 프로필

토빌

질문자

2021.07.09

해봤는데 이젠 업로드 버튼을 눌러도 url만 변하고 아무런 변화가 없네요...ㅎ

자꾸 물어봐서 죄송해요ㅠㅠ

src/index.js는 다음과 같습니다.

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

오 그래도 에러는 이제 안난다는 말씀이신가요? 그러면 해당 문제는 고쳐진 것 같고..

브라우저 개발자도구에서 어떤 로그가 보이나요?

0

index.js 코드를 볼 수 있을까요~?