#reactjs #mongodb #express
#reactjs #mongodb #экспресс
Вопрос:
Я создаю простое приложение MERN stack, в котором пользователи оставляют отзывы о кафе.
Мне нужна функциональность, с помощью которой пользователь может щелкнуть по названию кафе, что приведет к перенаправлению на просмотр со всеми отзывами об этом конкретном кафе — любые предложения о том, как я могу это сделать?
Структура базы данных Mongo Atlas
Database
|
--cafes (collection)
-- _id:5ffb7a6bf32d1b27ac8474d9
cafeName:"Customs Coffee
photoURL:"https://*******
--reviews (collection)
--_id:5ffb95b75624dd13d825ea5e
userName:"Josh"
stars:"4"
title:"Second review of customs coffee"
photo:"photoURL.com"
blurb: "this is the blurb for the second review of customs"
cafe:"Customs Coffee"
createdAt:2021-01-11T00:03:03.842 00:00
Компоненты, отображающие список кафе
CafeList.jsx
import React, {useState, useEffect} from 'react'
import axios from 'axios'
import Cafe from './Cafe'
const CafeList = () => {
const [cafes, setCafe] = useState([])
useEffect(() => {
axios.get('/api/all-cafes')
.then(cafe => {
setCafe(cafe.data)
})
.catch(err => {
console.log(err)
})
},[])
return(
<div className = 'cafe-container-container'>
<h2>Cafes</h2>
<Cafe cafes = {cafes}/>
</div>
)
}
export default CafeList
Cafe.jsx
import React from 'react'
import {Link} from 'react-router-dom'
const Cafe = (props) => {
const {cafes} = props
return(
<div>
{
cafes.map(cafe =>{
const {cafeName,photoURL} = cafe
return (
<Link to = '/cafe-reviews/' style={{ textDecoration: 'none' }} >
<div className = 'cafe-container'>
<h2>{cafeName}</h2>
<img src = {photoURL}></img>
</div>
</Link>
)
})
}
</div>
)
}
export default Cafe
.. и вот пустой компонент, в котором я в конечном итоге хочу отображать обзоры, относящиеся к конкретному кафе:
import react from 'react'
const CafeReviews = () => {
return(
<div>
This is the cafe review list
</div>
)
}
export default CafeReviews
В нынешнем виде, когда вы нажимаете на любое кафе, оно перенаправляется на CafeReviews
компонент, но, как я уже упоминал, я бы хотел вместо этого отображать обзоры, относящиеся к конкретному кафе, на которое нажимается. Общим элементом между двумя коллекциями является название cafe ( cafeName
и «cafe` соответственно), поэтому я думаю, что мне придется выполнить какое-то объединение, используя это свойство.
Наконец, вот экспресс-маршруты, которые я написал: server.js
app.get('/api/all-reviews', (req,res) => {
Review.find()
.then((result) => {
res.send(result)
})
.catch(err => {
console.log(err)
})
})
app.get('/api/all-cafes', (req,res) => {
Cafe.find()
.then((result) => {
res.send(result)
})
.catch(err => {
console.log(err)
})
})
app.post('/api/add-review',(req,res) => {
const review = new Review(req.body)
review.save()
.then(() => {
console.log('review successfully posted')
res.status(200)
})
.catch(err => {
console.log(err)
})
})
Ответ №1:
Я лично добавил бы ссылку на Кафе в вашу коллекцию отзывов вместо простого общего поля, такого как название кафе. Если вы используете mongoose для определения вашей схемы mongo, это будет примером вашего поля ссылки cafe в вашей коллекции отзывов
_id: mongoose.Schema.Types.ObjectId,
userName: {Type: String, required: true},
cafeReference: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Cafe',
required: true,
},
... etc (your other collection fields)
Затем создайте конечную точку API на своем серверном сервере, которая получает обзоры cafe по идентификатору cafe. А затем при рендеринге компонента CafeReviews вы будете отправлять запрос GET с этим идентификатором cafe в полезной нагрузке вашего запроса. Затем, наконец, метод Mongo «find» принимает параметры, по которым он может искать запрошенные документы. Связывание документов — https://docs.mongodb.com/manual/reference/method/db.collection.find /
В вашем случае пример будет следующим:
Review.find({cafeReference: cafeId})
Также у mongoose есть отличный метод объединения полей из 2 коллекций (эквивалент sql join), называемый «заполнить» — https://mongoosejs.com/docs/populate.html .
Также запустите запрос «получить отзывы по идентификатору кафе» внутри метода жизненного цикла реакции componentDidMount. Вот как это реализовать в перехватах — https://reactjs.org/docs/hooks-effect.html
Надеюсь, это поможет,