작성
·
257
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
아래와 같이 뜹니다!
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)
0
여기 있습니다~
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;
BrowserRouter를 app.js의 상위인 src/index.js로 두시고 해보시겠어요~?
현재는 BrowserRouter를 app.js에서 Wrapping하고 있습니다.
https://github.com/yansfil/grab-market-client/blob/main/src/index.js
해봤는데 이젠 업로드 버튼을 눌러도 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
App.js에 BrowserRotuer는 지우신거 맞죠?
Github 소스코드 공유해주시면 제가 좀이따 확인해볼게요~!