在src文件夹中,我有以下组件,
- addNotes.js
import noteContext from '../context/notes/noteContext';
const AddNote = () => {
const context = useContext(noteContext);
const [note, setNote] = useState({title:" ",description:" ",tag:"default "})
const { addNote } = context;
const handleClick = (e) => {
e.preventDefault();
addNote(note.title, note.description,note.tag);
}
const onChange = (e) => {
setNote({...note,[e.target.name]:e.target.value})
}
return (
<div> <div className="container my-3">
<h2>ADD A NOTE</h2>
{/* FORM */}
<form className='my-3'>
<div className="mb-3">
<label htmlFor="exampleInputEmail1" className="form-label">Title</label>
<input type="text" className="form-control" id="title" name='title' onChange={onChange} aria-describedby="emailHelp" />
</div>
<div className="mb-3">
<label htmlFor="description" className="form-label">Description</label>
<input type="text" className="form-control" id="description" name='description' onChange={onChange} />
</div>
<div className="mb-3 form-check">
<input type="checkbox" className="form-check-input" id="exampleCheck1" />
<label className="form-check-label" htmlFor="exampleCheck1">Check me out</label>
</div>
<button type="submit" className="btn btn-primary" onClick={handleClick}>ADD NOTE</button>
</form>
</div></div>
)
}
export default AddNote
- Home.js
- Navbar.js
- NoteItem.js
- Notes.js
- noteContext.js
- NoteState.js
import Notes from './Notes'
export default function Home() {
return (
<div >
<Notes/>
</div>
)
}
import { NavLink ,useLocation} from "react-router-dom";
export default function Navbar() {
let location = useLocation();
useEffect(()=>{
// console.log(location.pathname);
},[location])
return (
<>
<nav className="navbar navbar-expand-lg bg-light navbar-light py-3 shadow-sm">
<div className="container">
<NavLink className="navbar-brand fw-bold f-4 fs-2" to="/">iNotebook</NavLink>
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mx-auto mb-2 mb-lg-0 fs-4">
<li className="nav-item">
<NavLink className={`nav-link ${location.pathname === "/"?"active":" "}` }aria-current="page" to="/">Home</NavLink>
</li>
<li className="nav-item">
<NavLink className={`nav-link ${location.pathname === "/about"?"active":" "}` }to="/about">About</NavLink>
</li>
</ul>
<form className="d-flex" role="search">
<input className="form-control me-2" type="search" placeholder="Search" aria-label="Search" />
<button className="btn btn-outline-dark" type="submit">Search</button>
</form>
</div>
</div>
</nav>
</>
)
}
4import React,{useContext} from 'react'
import noteContext from '../context/notes/noteContext';
const NoteItem = (props) => {
const context = useContext(noteContext);
const {deleteNote} =context;
const {note} = props;
// console.log(note.tittle);
return (
<div className='col-md-3 '>
<div className="card my-3">
<div className="card-body">
<div className="d-flex align-items-center">
<h5 className="card-title">{note.tittle}</h5>
<i className="fa-solid fa-trash-can mx-2" onClick={()=>{deleteNote(note._id)}}></i>
<i className="fa-solid fa-pen-to-square mx-2"></i>
</div>
<p className="card-text">{note.description} </p>
</div>
</div>
</div>
)
}
export default NoteItem
import noteContext from '../context/notes/noteContext';
import AddNote from './AddNote';
import NoteItem from './NoteItem';
const Notes = () => {
const context = useContext(noteContext);
const { notes, getNotes } = context;
useEffect(() => {
getNotes()
}, [])
console.log(notes);
if(notes.length>0){
return (<>
<AddNote />
<div className=" row my-3 mx-3">;
<h3>YOUR NOTE</h3>
{notes.map((note,index) => {
return <NoteItem key={index} note={note} />
})}
</div>
</>
)}else{
return (
<div>Loading....</div>
)
}
}
export default Notes;
然后在src中,我有一个名为context的文件夹还有一个名为notes的文件夹。还有两个文件
import { createContext } from "react";
const noteContext = createContext();
export default noteContext;
import { useState } from "react";
import NoteContext from "./noteContext";
const NoteState = (props) => {
const host = "http://localhost:5000"
const notesInitial = [];
const [notes, setNotes] = useState(notesInitial)
// FETCH A NOTE
const getNotes = async () => {
// API CALL
const response = await fetch(`${host}/api/notes/fetchallnotes`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
"auth-token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNjJiNDRmMjIzNWVhZmNkM2FhODRmMTg1In0sImlhdCI6MTY1NTk4NzgyNH0.LRueOf_bDWJB6NJ5jmN-ZQxStPPUt0ppW2G0s5VcRr4"
}
});
const json = await response.json()
console.log(json);
setNotes(json);
}
// ADD A NOTE
const addNote = async (title, description, tag) => {
// API CALL
const response = await fetch(`${host}/api/notes/addnote`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"auth-token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNjJiNDRmMjIzNWVhZmNkM2FhODRmMTg1In0sImlhdCI6MTY1NTk4NzgyNH0.LRueOf_bDWJB6NJ5jmN-ZQxStPPUt0ppW2G0s5VcRr4"
},
body: JSON.stringify({ title, description, tag })
});
console.log("Adding a new note");
const note = {
"_id": "62b45b1eff7f",
"user": "62b44f2235eafcd3aa84f185",
"title": title,
"description": description,
"tag": tag,
"date": "2022-06-24T10:55:43.455Z",
"__v": 0
};
setNotes(notes.concat(note))
}
// DELETE A NOTE
// TODO API CALL
const deleteNote = (id) => {
console.log("This is deleting node" + id);
const newNotes = notes.filter((note) => { return note._id !== id })
setNotes(newNotes)
}
// EDIT A NOTE
const editNote = async (id, title, description, tag) => {
// API CALL
const response = await fetch(`${host}/api/notes/updatenote/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
"auth-token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNjJiNDRmMjIzNWVhZmNkM2FhODRmMTg1In0sImlhdCI6MTY1NTk4NzgyNH0.LRueOf_bDWJB6NJ5jmN-ZQxStPPUt0ppW2G0s5VcRr4"
},
body: JSON.stringify({ title, description, tag })
});
// const json = response.json()
// LOGIC TO EDIT IN CLIENT
for (let index = 0; index < notes.length; index++) {
const element = notes[index];
if (element._id === id) {
element.title = title;
element.description = description;
element.tag = tag;
}
}
}
return (
<NoteContext.Provider value={{ notes, addNote, deleteNote, editNote, getNotes }}>
{props.children}
</NoteContext.Provider>
)
}
// console.log(notes);
export default NoteState;
我的App.js看起来像下面,
import './App.css';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Navbar from './components/Navbar';
import Home from './components/Home';
import About from './components/About';
import NoteState from './context/notes/NoteState';
import Alert from './components/Alert';
function App() {
return (
<>
<NoteState>
<Router>
<Navbar />
{/* <Alert message="this is amazing react course"/> */}
<div className="container">
<Routes>
<Route path="/" exact element={<Home />} />
<Route path="/about" exact element={<About />} />
</Routes>
</div>
</Router>
</NoteState>
</>
);
}
export default App;
这里还有两个我没有包括的文件,它们是alert.js和About.js,因为它们没有用处。
这是与上下文API代码一起存在的所有组件的全部代码。在noteItem.js中发生的主要问题是我在控制台获得带有id和标题的笔记数组,但当我在组件中使用它作为{note.title}
或{note.description}
时。显示未定义
const Notes = () => {
const context = useContext(noteContext);
const { notes, getNotes } = context;
useEffect(() => {
getNotes()
}, [])
if(notes.length>0){
return (<>
<AddNote />
<div className=" row my-3 mx-3">;
<h3>YOUR NOTE</h3>
{notes.map((note,index) => {
return <NoteItem key={index} note={note} />
})}
</div>
</>
)}else{
return (
<div>Loading....</div>
)
}
}
export default Notes;