我有一个使用Express和React构建的简单Web应用程序。我正在通过我的快递服务器提供整个前端React包。
当前,我的启动脚本运行良好,它构建了前端代码并启动了我的Express服务器。当我在浏览器中导航至该应用程序时,所有内容均可找到,前端和后端。但是,当我运行开发脚本时,后端端点不起作用,因此出现错误,并且前端永不渲染。
整个源可以找到here,但我将相关文件放在下面:
webpack.config.js:
module.exports = {
mode: 'development',
entry: './client/index.js',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
}, {
test: /\.css$/,
loader: 'style-loader'
}, {
test: /\.css$/,
loader: 'css-loader',
query: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
output: {
path: __dirname + '/dist',
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: './dist'
},
devtool:"#eval-source-map"
};
package.json:
{
"name": "contacts",
"version": "1.0.0",
"description": "A simple contacts app written using React, Node, and Mongo",
"main": "index.js",
"scripts": {
"start": "npx webpack --mode=development && node server/server.js",
"build": "webpack --mode=development",
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --config ./webpack.config.js --mode development"
},
...
感谢您的帮助!
答案 0 :(得分:0)
它运行在http://localhost:8080
上,但是,您有一个奇怪的实现,将整个ReactDOM.render
函数包装在promise中。此外,如果数据丢失,则会导致TypeError: this.props.contacts.map is not a function
并且什么都不会显示。
API提取调用应放在组件的componentDidMount
生命周期内。然后,class component
应该根据响应返回某个conditionally rendered组件。您需要处理所有存在数据,数据丢失和/或API错误的情况(否则,它将使您的应用程序崩溃)。
有效的API示例(具体看一下containers/Users/index.js
或下面编写的示例代码):
容器/用户/index.js
import React, { Component } from "react";
import app from "../../utils/axiosConfig";
import ShowData from "../../components/ShowData";
import ShowError from "../../components/ShowError";
import ShowLoading from "../../components/ShowLoading";
export default class App extends Component {
state = {
data: [],
hasError: "",
isLoading: true
};
componentDidMount = () => {
window.setTimeout(() => {
this.fetchData("users"); // calling "fetchData" after 1.5seconds (not necessary, but this way, you'll see a "Loading" component when data isn't present yet)
}, 1500);
};
fetchData = url =>
app
.get(`${url}`) // makes a request to the API
.then(res => { // handles a successful API response
if (!res.data) throw new Error("No data was found!");
this.setState({ isLoading: false, data: res.data });
})
.catch(err => // handles an API error or no data response
this.setState({ isLoading: false, hasError: err.toString() })
);
handleClick = () => {
this.setState({ isLoading: true, data: [] }, () => {
this.fetchData("todos");
});
};
// the code below utilizes a ternary operator: if cond ? then : else
// (shorthand for if/else or if/elseif/else ...etc)
// the code below can be read as: if isLoading is true, then return
// "<ShowLoading/>"; if it's false, but there was an error, then
// return "<ShowError ... />", else if isLoading is false and
// hasError is false, then return "<ShowData ... />"
render = () => (
<div className="app-container">
{this.state.isLoading ? (
<ShowLoading />
) : this.state.hasError ? (
<ShowError error={this.state.hasError} />
) : (
<ShowData data={this.state.data} handleClick={this.handleClick} />
)}
</div>
);
}