当我在服务器上收到带有数据的POST请求时,我想在客户端刷新信息。
目前它看起来像这样。我在服务器端有POST请求:
final AuditReader auditReader = AuditReaderFactory.get( session );
List results = auditReader.createQuery()
.forRevisionsOfEntity( Periodicity.class, true, false )
// add the revision number predicate
.add( AuditEntity.revisionNumber().eq( revisionId ) )
// add the instrument predicate
.add( AuditEntity.property( "id.instrumentId" ).eq( instrumentId ) )
.getResultList();
当我成功插入数据库时,我想自动刷新客户端。要显示来自标记的信息'来自数据库的JSON我正在使用MarkersList组件和MarkerPage组件:
MarkersList.js
app.post('/login',jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400);
if(req.body){
console.log(req.body);
mongodb.connect(dbUrl,function(err,db){
db.collection('markers').insertOne(req.body);
});
return res.sendStatus(200);
}
})
MarkerPage.js
export default function MarkersList({markers}) {
const emptyMessage=(
<p> There are no coordinates to display </p>
);
const markersList=(
<div>{markers.map(marker=> <p>{marker.title}</p>)}</div>
);
return(
<div>
{markers.length === 0 ? emptyMessage:markersList}
</div>
);
}
MarkersList.propTypes={
markers:React.PropTypes.array.isRequired
}
actions.js
import React from 'react';
import MarkersList from './MarkersList';
import {connect} from 'react-redux';
import {fetchMarkers} from './actions';
class Markers extends React.Component{
componentDidMount(){
this.props.fetchMarkers();
}
render(){
return(
<div>
<p>LISTA</p>
<MarkersList markers={this.props.markers}/>
</div>
)
}
}
Markers.propTypes={
markers: React.PropTypes.array.isRequired,
fetchMarkers: React.PropTypes.func.isRequired
}
function mapStateToProps(state){
return{
markers:state.markers
}
}
export default connect(mapStateToProps,{fetchMarkers})(Markers);
index.js -client side:
export const SET_MARKERS='SET_MARKERS';
export function setMarkers(markers){
return{
type:SET_MARKERS,
markers
}
}
export function fetchMarkers(){
return dispatch => {
fetch('/api/markers')
.then(res=>res.json())
.then(data=>dispatch(setMarkers(data.markers)));
;
}
}
如何从服务器端发出类似动作的内容,以便在客户端显示数据库的当前状态?
答案 0 :(得分:1)
您可以通过多种方式执行服务器端驱动的客户端更新:
非常不满意,因为它要求您预测服务器端代码的执行时间,并且它实际上并不是由服务器驱动的。 以下是执行此类思考的两种解决方案:
使用像react-timer-mixin之类的mixin每隔X秒在MarkerPage组件中调用this.props.fetchMarkers(在下面的示例中为2秒)。
import React from 'react';
import TimerMixin from 'react-timer-mixin';
import MarkersList from './MarkersList';
import {connect} from 'react-redux';
import {fetchMarkers} from './actions';
class Markers extends React.Component{
componentDidMount(){
this.props.fetchMarkers();
TimerMixin.setTimeout(() => {
this.props.fetchMarkers();
},2000);
}
render(){
return(
<div>
<p>LISTA</p>
<MarkersList markers={this.props.markers}/>
</div>
)
}
}
Markers.propTypes={
markers: React.PropTypes.array.isRequired,
fetchMarkers: React.PropTypes.func.isRequired
}
function mapStateToProps(state){
return{
markers:state.markers
}
}
export default connect(mapStateToProps,{fetchMarkers})(Markers);
为了避免混淆,它会向你保证定时器会被组件破坏。
在我看来,确保数据重新加载并不是组件的目的。它的唯一目的是显示。
为了避免从组件重新加载数据,我更喜欢使用将分派给商店的独立代码。它不会干扰组件代码。 以下是根据我的申请改编的一个例子:
index.js -client side:
import {fetchMarkers} from './actions';
function startAutoReloadMarkers(store) {
window.setInterval(() => {
store.dispatch(fetchMarkers());
}, 2000);
}
const store= createStore(
rootReducer,
composeWithDevTools(
applyMiddleware(thunk)
)
)
startAutoReloadMarkers(store)
这是从反应/减少优势中获利的一种非常好的方式。 这是我在我的应用程序中使用的解决方案:
在服务器端登录代码中:
// On user login (using a websocket), I trigger a call to an external service wich will respond later (my seneca service is the equivalent of your mongodb insert)
seneca().use(senecaTransactions).act({ cmd: handleAutomaticOperations, userId: user._id }, (error, transactions) => {
if(error) {
// You don't need thios
reject(error);
} else {
// You don't need this
resolve(true);
// Here I will notify the client that some transactions have been updated/added
socket.emit(TRANSACTION_UPDATED, transactions);
}
});
index.js -client side:
import Socket from '../Socket';
import { TRANSACTION_UPDATED } from '../constants/SocketActions';
export function startTransactionsMiddleware(store) {
Socket.on(TRANSACTION_UPDATED, (transaction) => {
// The equivalent of your dispatch(fetchMarkers()
store.dispatch(transactionUpdated(transaction));
});
}
// Same think that the previous example
startTransactionsMiddleware(store);
This way once the TRANSACTION_UPDATED is trigerred in the server my display will be updated thanks to redux.
如果您需要一些帮助来实施第二个解决方案,请不要犹豫。