Есть ли способ, которым я могу передавать свойство между компонентами, не используя объект props?

#reactjs #express #mongoose

#reactjs #выразить #мангуст

Вопрос:

У меня есть компонент, который отображает список кафе. Внутри этого компонента ( CafeList.jsx ) выполняется запрос axios, который возвращает список кафе, который отображается и отображается в браузере.
Я бы хотел, чтобы пользователи могли нажимать на кафе, а затем перенаправляться на страницу с конкретной информацией об этом конкретном кафе (на данном этапе это CafeReview.jsx ).

Мне нужно передать идентификатор кафе ( _id ) из CafeList в CafeReviews , чтобы я мог использовать его в запросе axios, который возвращает конкретные данные о кафе, на которое был нажат. Есть предложения? Кроме того, есть ли у меня правильный общий подход?

Компоненты

CafeList.jsx

 import React, {useState, useEffect} from 'react'
import axios from 'axios'
import {Link} from 'react-router-dom'


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>
                {
                cafes.map(cafe =>{
                    const {cafeName,photoURL,_id} = cafe
                    
                    return (
                    <Link to = {`/cafe-reviews/${_id}`} style={{ textDecoration: 'none' }} >
                        <div className = 'cafe-container'>
                            <h2>{cafeName}</h2>
                            <img src = {photoURL}></img>
                        </div>
                    </Link>
                    )
                })
            }
            </div>

    )
}

export default CafeList
 

CafeReviews.jsx

 import React,{useState, useEffect} from 'react'
import axios from 'axios'

const CafeReviews = () => {
  const [cafe,setCafe] = useState([])

  useEffect(() => {
    axios.get('/api/cafe/:id')
    .then(result => {
        setCafe(result.data)
    })
  },[])

  return(
      <div>
          {
             cafe.map(item => {
                 return (
                     <h2>{item.cafeName}</h2>
                 )
             }) 
          }
      </div>
  )
}

export default CafeReviews
 

Маршруты и модели данных

ПОЛУЧИТЬ кафе по идентификатору:

 app.get('/api/cafe/:id', (req,res) => {
    const id =req.params.id
    Cafe.findById(id)
    .then(result => {
        res.send(result)
    })
    .catch(err => {
        console.log(err)
    })
})
 

Модель Кафе:

 
const mongoose = require('mongoose')
const Schema = mongoose.Schema

const cafeSchema = new Schema({
    cafeName:String,
    photoURL:String,
}, {timestamps:true})

const Cafe = mongoose.model('cafes', cafeSchema)

module.exports = Cafe
 

Маршрутизатор:

 import React from 'react'
import AddReview from './components/AddReview'
import Main from './components/Main'
import AllReviews from './components/AllReviews'
import CafeReviews from './components/CafeReviews'
import './styles.css'

import {BrowserRouter as Router, Switch, Route} from 'react-router-dom'

const App = () => {
  return(
    <Router>
    <div>
      <Switch>
      <Route path ='/' exact component = {Main}/>
      <Route path ='/add-review' component = {AddReview}/>
      <Route path ='/all-reviews' component = {AllReviews}/>
      <Route path ='/cafe-reviews/:id' component = {CafeReviews}/>
      </Switch>
    </div>
    </Router>
  )
}

export default App;
 

Комментарии:

1. Я не понимаю, у вас уже есть доступ к идентификатору кафе на странице отзывов, он указан в URL? Вы можете использовать react router, чтобы получить оттуда идентификатор и использовать его в запросе

2. axios.get('/api/cafe/:id') выглядит не совсем правильно. Я уверен, что вы хотели получить доступ id к параметрам соответствия и создать допустимый URL-адрес для запроса GET.

3. @Jayce444 Я думаю, я понимаю, что вы говорите, но не могли бы вы уточнить? Я обновил свой вопрос, чтобы включить мой маршрутизатор.

Ответ №1:

Поскольку компонент CafeReviews напрямую отображается с помощью a <Route/> , по умолчанию ему передаются все реквизиты маршрутизатора react. Оттуда вы можете получить доступ к параметрам, которые будут содержать :id это конкретное кафе в URL. Так что попробуйте что-то вроде этого:

 const CafeReviews = ({ match }) => {
  const [cafe,setCafe] = useState([])

  useEffect(() => {
    axios.get(`/api/cafe/${match.params.id}`)
    .then(result => {
        setCafe(result.data)
    })
  },[])
 

Не тестировал, возможно, потребуется проверить документы react-router-dom , чтобы убедиться, что это правильная форма объекта и тому подобное, но в целом это способ доступа к параметрам внутри компонента