我有问题。我无法刷新我的反应组件/页面而没有“无法获取/当前页面”。我已经浏览了你一段时间,发现了一些可以解决我问题的链接:
BrowserHistory的HashHistory。互联网说我应该使用BrowserHistory进行制作 - 但是hashHistory更容易。它们都非常复杂。我不知道如何将它实现到我当前的代码中。
这是我的app.js文件:
/*global $:true*/
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
import './scss/app.scss';
// Component imports
import Home from './components/home';
import Archive from './archive';
// Image import
import loadImg from './images/tits.gif';
class App extends Component {
// Function for anchorlinks
hashLinkScroll() {
const { hash } = window.location;
if (hash !== '') {
// Push onto callback queue so it runs after the DOM is updated, this is required when navigating from a different page so that the element is rendered on the page before trying to getElementById
setTimeout(() => {
const id = hash.replace('#', '');
const element = document.getElementById(id);
if (element) element.scrollIntoView();
}, 100);
}
}
// 1. Render site-loader gif
// 2. React Router component wraps all of the routes we are going to define - Archive and Home. Each route will be identified in a <Route> component. The <Route> component will take two properties: path and component. When a path matches the path given to the <Route> component, it will return the component specified.
render() {
return (
<div>
<div className="loaderSmall">
<img className="loadingImg" src={loadImg} width="400"/>
</div>
<Router history={browserHistory} onUpdate={this.hashLinkScroll}>
<Route path={'/archive'} component={Archive} />
<Route path={'*'} component={Home} />
</Router>
</div>
);
};
// When Component has rendered, window.addEventListener adds event "load" and calls handleLoad function
componentDidMount() {
window.addEventListener('load', this.handleLoad);
}
// Fade out site-loader
handleLoad() {
$(".loaderSmall").delay(500).fadeOut("slow");
}
};
ReactDOM.render (
<App/>,
document.getElementById('app')
)
// Hot Module Replacement API (injecting code)
if (module.hot) {
module.hot.accept();
}
export default App;
..这是我的菜单组件,当我在“/ archive”组件上时呈现:
import React, { Component } from 'react';
import { Link } from 'react-router';
//Menu component renders menu Link
class Menu extends Component {
render() {
return (
<header>
<nav>
<ul>
<li><Link to={'/#top'}>Home</Link></li>
<li><Link to={'/#about'}>About</Link></li>
<li><Link to={'/archive'}>Archive</Link></li>
<li className="contactMobile"><a href="mailto:magdamargaretha@gmail.com?Subject=magdenmagden">Contact</a></li>
<li className="contactWeb"><Link to={'/#contact'}>Contact</Link></li>
</ul>
</nav>
</header>
);
}
}
export default Menu;
..这是我的另一个菜单,当我在root上我想要可滚动的hashlinks时呈现:
import React, { Component } from 'react';
import { Link } from 'react-router';
import Scrollchor from 'react-scrollchor';
//Menu component renders menu Link
class MenuB extends Component {
render() {
return (
<header>
<nav>
<ul>
<li><Scrollchor to="#top" animate={{offset: 20, duration: 800}}>Home</Scrollchor></li>
<li><Scrollchor to="#about" animate={{offset: 0, duration: 800}}>About</Scrollchor></li>
<li><Link to={'/archive'}>Archive</Link></li>
<li className="contactMobile"><a href="mailto:magdamargaretha@gmail.com?Subject=magdenmagden">Contact</a></li>
<li className="contactWeb"><Scrollchor to="#contact" animate={{offset: 20, duration: 800}}>Contact</Scrollchor></li>
</ul>
</nav>
</header>
);
}
}
export default MenuB;
我的webpack.config.js文件:
// DEVELOPMENT
const webpack = require('webpack');
const path = require('path');
const entry = [
'webpack-dev-server/client?http://localhost:8080', // bundle the client for webpack-dev-server and connect to the provided endpoint
'webpack/hot/only-dev-server', // bundle the client for hot reloading only- means to only hot reload for successful updates
'./app.js'
]
const output = {
path: path.join(__dirname, 'dist'),
publicPath: '/dist',
filename: 'bundle.min.js'
}
const plugins = [
new webpack.HotModuleReplacementPlugin(), // enable HMR globally
new webpack.NamedModulesPlugin() // prints more readable module names in the browser console on HMR updates
]
const config = {
context: path.join(__dirname, 'src'),
entry: entry,
output: output,
devtool: "inline-source-map",
module: {
rules: [
{
// test: /\.(js|jsx)$/,
// exclude: /node_modules/,
// include: path.join(__dirname, 'src'),
// use: {
// loader: "eslint-loader",
// options: {
// failOnWarning: false,
// failOnError: false
// }
// }
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.join(__dirname, 'src'),
use: {
loader: "babel-loader"
}
},
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: { limit: 10000, name: './images/[name].[ext]' }
}]
},
{
test: /\.(sass|scss)$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}
]
},
performance: {
maxAssetSize: 400000000,
maxEntrypointSize: 400000000,
hints: 'warning'
},
plugins: plugins,
externals: {
jquery: 'jQuery'
}
}
module.exports = config
我的webpack.config.prod.js文件:
// PRODUCTION
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const entry = {
app: path.join(process.cwd(), 'src/app.js')
}
const output = {
path: path.join(__dirname, 'dist'),
filename: 'bundle.min.js',
}
const plugins = [
new webpack.DefinePlugin({
// 'process.env.NODE_ENV': JSON.stringify('production')
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
mangle: false,
compress: {
warnings: false
}
}),
new ExtractTextPlugin('bundle.css'), // creation of HTML files to serve your webpack bundles
new HtmlWebpackPlugin({
template: 'index-template.html'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'bundle',
filename: '[name].common.js'
})
]
const config = {
context: path.join(__dirname, 'src'),
entry: entry,
output: output,
devtool: "source-map",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.join(__dirname, 'src'),
use: "babel-loader"
},
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: { limit: 10000, name: './images/[name].[ext]' } // Convert images < 10k to base64 strings (all in images folder)
}]
},
{
test: /\.(sass|scss)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: (loader) => [ require('autoprefixer')() ]
}
},
'sass-loader',
]
})
}
]
},
plugins: plugins,
externals: {
jquery: 'jQuery'
}
}
module.exports = config;
..我知道有更好的方法来做到这一点,而不是让两个菜单组件在不同的页面上呈现,但我现在只是做了这个解决方案。问题是我不知道如何转换这个到了BrowserHistory的HashHistory而没有失去我的逻辑。任何提示/输入都会非常感激,并且已经持续了好几个星期&lt; 3
答案 0 :(得分:0)
无法GET / currentPage?
对于页面刷新时的browserHistory
,在服务器端请求/currentPage
。
在后端,您的服务器没有定义此路径(请求的资源)。
您需要将其实施为固定Cannot GET
问题以进行页面刷新。
假设nodejs
app.use(express.static(__dirname));
//will serve index.html for every page refresh.
app.use('*',(req,resp)=>{
res.sendFile(path.resolve(__dirname+'/index.html'))
})
app.listen(someport)
这将为每次刷新页面加载index.html
页面。
一旦index.html
加载了所需的JS&amp;反应路由器,
路由器将触发路由,并且相应的组件将被渲染。
答案 1 :(得分:0)
@Panther解决了这个问题。为了能够在我的开发环境中刷新页面,我不得不添加:
historyApiFallback: {
disableDotRule: true
}
到我的webpack dev.server文件:
var WebpackDevServer = require('webpack-dev-server');
var webpack = require('webpack');
// requiring my webpack configuration
var config = require('./webpack.config.js');
var path = require('path');
var compiler = webpack(config);
// then spinning up a new dev server with some settings
var server = new WebpackDevServer(compiler, {
hot: true,
filename: config.output.filename,
publicPath: config.output.publicPath,
proxy: {
"/getMail": 'http://localhost:80/magdan/php/mailer.php',
"/getProducts": 'http://localhost:80/magdan/php/products.php'
},
stats: {
colors: true
},
historyApiFallback: {
disableDotRule: true
}
});
// its gonna listen to port 8080
server.listen(8080, 'localhost', function() {
console.log("Starting server on http://localhost:8080");
});