I'm very used to Rails but am adding React as a front-end for the first time and am hitting what I hope are very obvious beginner issues. I'm following this tutorial (roughly...with my own model structure), but it doesn't actually go over adding edit routes. (It's more CRD than CRUD for some reason...)
I have the following routes set up in my javascript/routes/index.jsx
:
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import MainNavbar from "../components/MainNavbar";
import Home from "../components/Home";
import Topics from "../components/Topics";
import Topic from "../components/Topic";
import NewTopic from "../components/NewTopic";
export default (
<Router>
<MainNavbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/topics" element={<Topics />} />
<Route path="/topic/:id" element={<Topic />} />
<Route path="/topic" element={<NewTopic />} />
</Routes>
</Router>
);
With this structure, it works perfectly fine. However, when I add a route for EditTopic
it disappears from the page and a server error pops up:
19:50:16 js.1 | [watch] build started (change: "app/javascript/routes/index.jsx") 19:50:16 js.1 | ✘ [ERROR] Could not resolve "../components/EditTopic" 19:50:16 js.1 | 19:50:16 js.1 | app/javascript/routes/index.jsx:8:22: 19:50:16 js.1 | 8 │ import EditTopic from "../components/EditTopic";
The routes I am adding are pretty simple. I use:
import EditTopic from "../components/EditTopic";
And for the actual route I have tried both:
<Route path="/topics/:id" element={<EditTopic />} />
And:
<Route path="/topics/:id" element={<EditTopic />} />
Both create the same error. Can anyone help out as to where I'm going wrong?
EDIT
I've got an initial EditTopic.jsx
set out based on the NewTopic.jsx
that actually works. I know it's probably full of errors, but I was going to learn/debug using this as a template:
import React, { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
const EditTopic = () => {
const navigate = useNavigate();
const [name, setName] = useState("");
const [definitions, setDefinitions] = useState("");
const [state_v_trait, setStateVTrait] = useState("");
const [measurement, setMeasurement] = useState("");
const [notes, setNotes] = useState("");
const stripHtmlEntities = (str) => {
return String(str)
.replace(/\n/g, "<br> <br>")
.replace(/</g, "<")
.replace(/>/g, ">");
};
const onChange = (event, setFunction) => {
setFunction(event.target.value);
};
const onSubmit = (event) => {
event.preventDefault();
const url = "/api/v1/topics/${this.state.id}";
if (name.length == 0 )
return;
const body = {
name: stripHtmlEntities(name),
definitions: stripHtmlEntities(definitions),
state_v_trait: stripHtmlEntities(state_v_trait),
measurement: stripHtmlEntities(measurement),
notes: stripHtmlEntities(notes)
};
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch(url, {
method: "PUT",
headers: {
"X-CSRF-Token": token,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
})
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error("Network response was not ok.");
})
.then((response) => navigate(`/topic/${response.id}`))
.catch((error) => console.log(error.message));
};
// CUE HTML
return (
<div className="container mt-5">
<div className="row">
<div className="col-sm-12 col-lg-6 offset-lg-3">
<h1 className="font-weight-normal mb-5">
Edit {name}.
</h1>
<form onSubmit={onSubmit}>
<div className="form-group">
<label htmlFor="topicName">Name</label>
<input
type="text"
name="name"
id="topicName"
className="form-control"
required
onChange={(event) => onChange(event, setName)}
/>
</div>
<div className="form-group">
<label htmlFor="topicDefinitions">Definitions</label>
<input
type="text"
name="definition"
id="topicDefinitions"
className="form-control"
onChange={(event) => onChange(event, setDefinitions)}
/>
</div>
<div className="form-group">
<label htmlFor="state_v_trait">State versus Trait</label>
<textarea
className="form-control"
id="state_v_trait"
name="state_v_trait"
rows="5"
onChange={(event) => onChange(event, setStateVTrait)}
/>
</div>
<div className="form-group">
<label htmlFor="measurement">How is this measured?</label>
<textarea
className="form-control"
id="measurement"
name="measurement"
rows="5"
onChange={(event) => onChange(event, setMeasurement)}
/>
</div>
<div className="form-group">
<label htmlFor="notes">Other Notes</label>
<textarea
className="form-control"
id="notes"
name="notes"
rows="5"
onChange={(event) => onChange(event, setNotes)}
/>
</div>
<button type="submit" className="btn custom-button mt-3">
Create Topic
</button>
<Link to="/topics" className="btn btn-link mt-3">
Back to topics
</Link>
</form>
</div>
</div>
</div>
);
// END HTML
};
export default NewTopic;
However, I have also tried it with this very stripped-down version of EditTopic.jsx
and the error still persists:
import React, { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
const EditTopic = () => {
};
export default NewTopic;
CodePudding user response:
Your export has the wrong name.
export default NewTopic
should be
export default EditTopic