Javascript 如何在同构React+;反应路由器应用
我想构建同构的Javascript 如何在同构React+;反应路由器应用,javascript,reactjs,react-router,Javascript,Reactjs,React Router,我想构建同构的react+react路由器应用程序,在谷歌搜索几天后,现在我可以实现只处理GET请求的同构应用程序 以下是我迄今为止所做的工作: 服务器使用react路由器处理所有请求 react路由器将调用驻留在与路由匹配的每个react视图中的fetchData函数 将之前获取的数据设置为React视图的道具,并将其呈现为string 将字符串和之前获取的数据作为全局变量窗口注入HTML,并将HTML传递给客户端 我们已成功从服务器渲染React应用程序 当客户端加载完我们的React应用程
react
+react路由器
应用程序,在谷歌搜索几天后,现在我可以实现只处理GET请求的同构应用程序
以下是我迄今为止所做的工作:
react路由器
处理所有请求react路由器
将调用驻留在与路由匹配的每个react视图中的fetchData
函数string
字符串
和之前获取的数据作为全局变量窗口注入HTML,并将HTML传递给客户端
窗口传递。作为React应用程序的道具,React不会重新渲染,因为状态相同
react router
具有有关params
和query
的信息。例如,如果我们有一个路由:/user/:uid
,客户端请求这个url:/user/1?foo=bar
,那么参数将是:{uid:1}
,查询将是{foo:'bar}
react路由器
然后可以将其传递给fetchData
函数,这样它就知道如何使用uid
为1的用户,并使用foo
查询执行任何操作
在POST请求中,react router
不知道POST参数。在服务器上,我们当然可以将POST参数传递给fetchData
函数,但是客户端呢?它不知道POST参数是什么
有没有一种方法可以让服务器告诉客户端POST参数?下面是我的登录视图示例。我希望当用户提交表单时,服务器将在出现错误时呈现错误消息,或者在成功时将其重定向到仪表板
fetchData.js
import whenKeys from 'when/keys';
export default (authToken, routerState) => {
var promises = routerState.routes.filter((match) => {
return match.handler.fetchData;
}).reduce((promises, match) => {
promises[match.name] = match.handler.fetchData(authToken, routerState.params, routerState.query);
return promises;
}, {});
return whenKeys.all(promises);
}
server.js
...
app.use((req, res) => {
const router = Router.create({
routes,
location: req.originalUrl,
onError: next,
onAbort: (abortReason) => {
next(abortReason);
}
});
router.run((Handler, state) => {
fetchData(authToken, state).then((data) => {
// render matched react View and generate the HTML
// ...
})
});
});
...
login.jsx
import React from 'react';
import DocumentTitle from 'react-document-title';
import api from './api';
export default class Login extends React.Component {
constructor(props) {
super(props);
// how to fill this state with POST parameters on error?
// how to redirect on success?
// and remember that this file will be called both from server and client
this.state = {
error: '',
username: '',
password: ''
};
}
// I saw some people use this function, but it'll only work if
// the form's method is GET
static willTransitionTo(transition, params, query) {
// if only we could read POST parameters here
// we could do something like this
transition.wait(
api.post('/doLogin', postParams).then((data) => {
transition.redirect(`/dashboard`);
});
);
}
render() {
return (
<DocumentTitle title="Login">
<div className="alert alert-danger">{this.state.error}</div>
<form method="post">
<input type="text" name="username" value={this.state.username} onChange={this._onFieldChange('username')} placeholder="Username" /><br />
<input type="password" name="password" value={this.state.password} onChange={this._onFieldChange('password')} placeholder="Password" /><br />
<button type="submit">Login</button>
</form>
</DocumentTitle>
);
}
_onFieldChange(name) {
var self = this;
return (e) => {
e.preventDefault();
var nextState = {};
nextState[name] = e.target.value;
self.setState(nextState);
}
}
}
从“React”导入React;
从“react document title”导入DocumentTitle;
从“/api”导入api;
导出默认类登录扩展React.Component{
建造师(道具){
超级(道具);
//如何在出错时用POST参数填充此状态?
//成功后如何重定向?
//请记住,此文件将同时从服务器和客户端调用
此.state={
错误:“”,
用户名:“”,
密码:“”
};
}
//我看到一些人使用这个功能,但只有在
//表单的方法是GET
静态WillTransition(转换、参数、查询){
//如果我们能在这里读取POST参数就好了
//我们可以这样做
过渡,等等(
api.post('/doLogin',postParams)。然后((数据)=>{
重定向(`/dashboard`);
});
);
}
render(){
返回(
{this.state.error}
登录
);
}
_onFieldChange(名称){
var self=这个;
返回(e)=>{
e、 预防默认值();
var nextState={};
nextState[name]=e.target.value;
自设置状态(nextState);
}
}
}
获取客户机上的“POST”数据
在客户端,您可以通过从表单输入中提取值来获取POST数据,该值与正常提交表单时在服务器上收到的值相对应
使用POST数据
现在您有了POST数据,但仍然存在一个问题,即无法将POST数据提供给React Router 0.13.x及更早版本中的转换挂钩。我创建了一个已关闭的,因为它是即将发布的v1.0版本重写的一部分
其要点是,位置现在有一个state对象,用于喷射出您需要的关于当前处理的请求/转换(这两个都是analagous)的任何额外数据:
- 在服务器上,您一次处理一个请求,因此您使用
req.body
- 在客户端上,将状态对象(包含提取的表单数据)传递给
transitiono()
现在,您的转换挂钩能够在两种环境中接收相同的表单数据。如果一切顺利,那太好了!如果事情进展不顺利,您需要一种方法来传递错误并重新呈现表单。新政府再次反对营救!使用transition.redirect()
并传递输入数据和错误,您现在拥有了需要在两侧渲染的所有内容
我现在不打算讨论更具体的细节,因为v1.0仍处于beta版本,而v0.13.x无论如何都没有必要的API来实现这一点,但我有一个存储库,它使用上面的pull请求来使用0.13.x实现此工作流,您可以同时查看:
- -自述文件概述了事物如何组合在一起
以下是该过程的一些粗略流程图:
服务器发布错误并重新显示
客户端发布错误并重新显示
我还创建了一些与此场景相关的可重用模块:
- 从表单的输入中获取数据,数据的格式应为该表单发布时使用的格式
- 提供
,即
路由器的
对
的反应-它处理触发到给定操作的转换,传递方法
和主体
(表单数据)状态-这将很快更新到v1.0
Great@insin,这正是我需要的。我希望React Router v1.0很快就能上市。你有一个例子@jonny buchanan吗?很高兴看到有人真的在编写同构应用程序,而不是JU