我在页面刷新或直接链接到不使用错误的嵌套URL时遇到常见错误。我没有得到常见的“无法获取”错误,而是得到一个错误“无法读取属性'类型'未定义”。因此,导航到此URL时我的状态数组未定义,例如:
http://localhost:3000/topics/glascow-coma-score
但此请求适用于刷新或直接链接: http://localhost:3000/topics/
编辑:这也是Heroku上的一个实现: https://emquick.herokuapp.com/topics/
https://emquick.herokuapp.com/topics/glascow-coma-score
我已阅读并尝试从这些主题,博客和文档来源实施解决方案:
React router dynamic routes not rendering component
React router: nesting static route within dynamic route refresh error
react-router dynamic segments crash when accessed
Unexpected token < error in react router component
https://tylermcginnis.com/react-router-cannot-get-url-refresh/
我已阅读所有/大部分评论和解决方案 在我的构建文件夹中,捆绑脚本的URL是绝对的,而不是相对的(如上面几个解决方案所建议的那样) 我正按照Tyler McGinnis博客文章的建议在我的服务器上提供通配符索引路由。 我正在使用create-react-app,所以我没有webpack package.json文件。
我并没有超出我的创建反应应用程序来解决这个问题,但在我的搜索中,我没有找到使用create-react-app发布到此问题的任何解决方案,包括任何人建议我必须弹出以解决问题。
这里有一些代码:
Server.js
const bodyParser = require('body-parser'),
passport = require('passport'),
mongoose = require('mongoose'),
express = require('express'),
dotenv = require('dotenv'),
morgan = require('morgan'),
seedDB = require('./seed'),
path = require('path'),
cors = require('cors'),
app = express()
const Resource = require('./models/resource'),
resources = require('./src/data/resources.json')
//Routes
const resourceRoutes = require('./routes/resources')
//Setup app
dotenv.config()
app.use(morgan('dev'))
app.use(cors())
//app.use(express.static('public'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
//SET STATIC ROUTE
// Priority serve any static files.
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.resolve(__dirname, 'build')));
} else {
app.use(express.static('public'))
}
//SERVER & DB
const port = process.env.PORT || 8080
// const db_url = process.env.MONGO_URI
const db_url = process.env.MLAB_URI
mongoose.connect(db_url)
//ROUTES
app.use('/api/resources/', resourceRoutes)
app.get("/*", function (req,res){
console.log("Index page sent")
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'index.html'))
})
})
const server = app.listen(port, function(req,res){
console.log("EMQuick server started on port " + port + "...")
console.log(process.env.NODE_ENV)
})
我的resources.js路由文件(这是我的应用程序的json数据来自哪里)
const express= require('express'),
router = express.Router(),
Resource = require('../models/resource')
router.get('/', function(req,res){
Resource.find({}, function (err, resources){
if (err) console.log(err)
res.json({resources})
})
})
router.get('/:id', function(req,res){
console.log("Im here in the backend API getting " + req.params.id)
Resource.findById( req.params.id, function (err, resource) {
if (err) console.log(err)
// console.log(resource.name)
res.json({resource})
})
})
router.post('/', function(req,res){
console.log(req.body.resource)
Resource.create(req.body.resource)
.then(function(newResource) {
res.status(201).json(newResource)
})
.catch(function(err){
res.send(err)
})
})
module.exports =router
客户端的我的App.js文件:
import React, {Component} from 'react'
import { Container } from 'semantic-ui-react'
import Navbar from './navigation/Navbar'
// import Home from './pages/Home'
import Categories from './categories/Categories'
import Category from './categories/Category'
import Topics from './topics/Topics'
import Topic from './topics/Topic'
import About from './pages/About'
import NewReference from './new/NewResource'
import * as apiCalls from './api'
import { Route, Switch } from 'react-router-dom'
// import FindArticle from './articles/FindArticle'
let payload = [], allResources = []
class App extends Component {
constructor (props) {
super(props)
this.state = {
resources: []
}
this.handleSearchChange = this.handleSearchChange.bind(this)
this.searchResources = this.searchResources.bind(this)
}
componentDidMount () {
this.loadResources()
}
async loadResources () {
payload = await apiCalls.getResources()
allResources = payload
console.log(allResources)
this.setState({resources: allResources.resources})
console.log(this.state)
}
handleSearchChange = (searchText) => {
console.log(searchText)
this.setState({
resources: this.searchResources(searchText)
})
}
searchResources(searchString){
return allResources.resources.filter((resource) => {
if (resource.name.toLowerCase().includes(searchString.toLowerCase())) {
console.log(searchString + " found in " + resource.name + " in Name field ")
return true
}
if (resource.pagebody && resource.pagebody.includes(searchString)) {
console.log(searchString + " found in " + resource.pagebody + " Pagebody ")
return true
}
if ((resource.description) && resource.description.includes(searchString)){
console.log(searchString + " found in " + resource.description + " Description ")
return true
}
return false
}
)
}
render () {
// const FindTopic = (props) => {
// return (
// <Topic resources={this.state.resources}
// {...props}
// />
// )
// }
return (
<Container >
<Navbar
resources = {this.state.resources}
handleSearch = {this.handleSearchChange}
/>
<Switch>
<Route exact path='/' component={About}/>
<Route path='/categories/:field'
render={(props) => <Category resources={this.state.resources} {...props} />}/>
<Route path='/categories'
render={(props) => <Categories resources={this.state.resources} {...props} />}/>
<Route path='/new' component={NewReference}/>
<Route path='/about'
render={(props) => <About resources={this.state.resources} {...props} />}/>
<Route path='/topics/:friendly'
render={(props) => <Topic resources={this.state.resources} {...props} />}/>
<Route path='/topics'
render={(props) => <Topics resources={this.state.resources} {...props} />}/>
</Switch>
</Container>
)
}
}
export default App
最后,我的API.js文件带有对我服务器的获取请求:
export async function createResource(resource){
const postURL = API_URL
return fetch(postURL, {
method: 'post',
headers: new Headers({
'Content-Type': 'application/json',
}),
body: JSON.stringify({resource: resource})
})
.then(resp => {
if (!resp.ok) {
if (resp.status >= 400 && resp.status < 500) {
return resp.json().then(data => {
let err = {errorMessage: data.message}
throw err
})
} else {
let err = {errorMessage: 'Please try again later, the server is not responding'}
throw err
}
}
// console.log(resp.json())
return resp.json()
})
}
这似乎是一个常见的错误,我已经尝试了我找到的所有建议,除了我不是直接使用webpack这一事实。如果它像弹出并使用package.json文件中的webpack解决方案一样简单,我也很想尝试,但不想旋转我的轮子。
**不是将通配符/ *路由服务到我的index.html文件解决了单个深度文件(如localhost:3000 / topics)的刷新问题,而不是更深层次的路由。