redux-saga/loadable-component 第一次获取没有等待,但所有接下来的都是
redux-saga/loadable-component first fetch not waited, but all the next ones yes
我无法制作合适的服务器端。
当我启动服务器并进行抓取时 http://localhost:3000/last-movie-releases
toPromise()
没有等待 第一次提取。但是我接下来做的所有其他都很好,服务器端就可以了。
下面只是我的代码片段。我在 class 构造函数中发送我的 redux 动作。 (就像每个人一样)
store
.runSaga(rootSaga)
.toPromise()
.then(() => {
console.log('sagas complete');
const html = ReactDOMServer.renderToString(jsx);
const css = sheets.toString();
res.send(
renderFullPage(html, css, serialize(store.getState()))
);
})
.catch(e => {
console.log(e.message);
res.status(500).send(e.message);
});
ReactDOMServer.renderToString(jsx);
store.close();
这是正常行为吗?
PS :我正在谈论的获取数据的传奇从 fork
开始,然后又是 fork
,然后是 call
。与 real-word repo
中的完全一样
我想知道我是否错过了某个地方 return。
/***********************************************
***************** UPDATE BELOW *****************
***********************************************/
我给你我的传奇(只有 2 个)
import {
take,
put,
call,
fork,
select,
delay,
all,
takeEvery,
takeLatest
} from 'redux-saga/effects';
import * as api from './api';
import * as actions from '../actions';
// each entity defines 3 creators { request, success, failure }
const { movies, movie } = actions;
function* fetchEntity(entity, apiFn, body) {
yield put(entity.request(body));
const { response, error } = yield call(apiFn, body);
if (response) yield put(entity.success(body, response));
else yield put(entity.failure(body, error));
}
// yeah! we can also bind Generators
export const fetchMovies = fetchEntity.bind(null, movies, api.fetchMovies);
export const fetchMovie = fetchEntity.bind(null, movie, api.fetchMovie);
/******************************************************************************/
/********************************* SAGAS **************************************/
/******************************************************************************/
function* sagaFetchMovies() {
yield call(fetchMovies);
}
function* sagaFetchMovie(movieId) {
yield call(fetchMovie, movieId);
}
/******************************************************************************/
/******************************* WATCHERS *************************************/
/******************************************************************************/
function* watchFetchMovies() {
while (true) {
yield take(actions.FETCH_MOVIES);
yield fork(sagaFetchMovies);
}
}
function* watchFetchMovie() {
while (true) {
const { movieId } = yield take(actions.FETCH_MOVIE);
yield fork(sagaFetchMovie, movieId);
}
}
export default function* root() {
yield all([fork(watchFetchMovies), fork(watchFetchMovie)]);
}
/***********************************************
***************** UPDATE BELOW *****************
***********************************************/
我告诉你我在哪里派遣我的行动;)
...
class Movie extends Component {
constructor(props) {
super(props);
this.state = { isSlideShowOpened: false };
const movie = props.app.movie.results.filter(e => e.id === Number(props.match.params.movieId));
if (movie.length === 0) {
props.fetchMovie(props.match.params.movieId); // <---- I dispatch here because componentWillMount is deprecated :s
}
}
...
...
class Movies extends PureComponent {
constructor(props) {
super(props);
this.state = {};
if (props.app.movies.results.length === 0) {
props.fetchMovies(); // <---- I dispatch here because componentWillMount is deprecated :s
}
}
...
@loadable/component 服务器端渲染有一个很大的警告 lol
@loadable/component 强制您为每条路线拆分代码,并最终使用回退(下载 js 包时的旋转器)
让我提醒你 @loadable/component 是市场上唯一能够为服务器端渲染做拆分代码的模块 lol
好吧,none 你的故事将由 @loadable/component 等待。我别无选择,这对 google 和 bing 来说并不是那么糟糕,我认为...
例如,我的 React 路由器看起来像这样
import React from 'react';
import loadable from '@loadable/component';
import Loading from './Exception/Loading';
const Home = loadable(() => import('./Home/index'), { fallback: <Loading /> });
const Movies = loadable(() => import('./Movies/index'), { fallback: <Loading /> });
const Movie = loadable(() => import('./Movie/index'), { fallback: <Loading /> });
const Slide1 = loadable(() => import('./Slides/Slide1'), { fallback: <Loading /> });
const Forbidden = loadable(() => import('./Exception/403'));
const NoMatch = loadable(() => import('./Exception/404'));
const ServerDown = loadable(() => import('./Exception/500'));
const indexRoutes = [
{
exact: true,
path: '/',
component: Home
},
{
exact: true,
path: '/last-movie-releases',
component: Movies
},
{
path: '/movie-details/:movieId/:slideshow?',
component: Movie
},
{
path: '/slide1',
component: Slide1
},
{ path: '/403', component: Forbidden },
{ path: '/404', component: NoMatch },
{ path: '/500', component: ServerDown },
{ name: 'NoMatch', component: NoMatch }
];
export default indexRoutes;
我无法制作合适的服务器端。
当我启动服务器并进行抓取时 http://localhost:3000/last-movie-releases
toPromise()
没有等待 第一次提取。但是我接下来做的所有其他都很好,服务器端就可以了。
下面只是我的代码片段。我在 class 构造函数中发送我的 redux 动作。 (就像每个人一样)
store
.runSaga(rootSaga)
.toPromise()
.then(() => {
console.log('sagas complete');
const html = ReactDOMServer.renderToString(jsx);
const css = sheets.toString();
res.send(
renderFullPage(html, css, serialize(store.getState()))
);
})
.catch(e => {
console.log(e.message);
res.status(500).send(e.message);
});
ReactDOMServer.renderToString(jsx);
store.close();
这是正常行为吗?
PS :我正在谈论的获取数据的传奇从 fork
开始,然后又是 fork
,然后是 call
。与 real-word repo
我想知道我是否错过了某个地方 return。
/***********************************************
***************** UPDATE BELOW *****************
***********************************************/
我给你我的传奇(只有 2 个)
import {
take,
put,
call,
fork,
select,
delay,
all,
takeEvery,
takeLatest
} from 'redux-saga/effects';
import * as api from './api';
import * as actions from '../actions';
// each entity defines 3 creators { request, success, failure }
const { movies, movie } = actions;
function* fetchEntity(entity, apiFn, body) {
yield put(entity.request(body));
const { response, error } = yield call(apiFn, body);
if (response) yield put(entity.success(body, response));
else yield put(entity.failure(body, error));
}
// yeah! we can also bind Generators
export const fetchMovies = fetchEntity.bind(null, movies, api.fetchMovies);
export const fetchMovie = fetchEntity.bind(null, movie, api.fetchMovie);
/******************************************************************************/
/********************************* SAGAS **************************************/
/******************************************************************************/
function* sagaFetchMovies() {
yield call(fetchMovies);
}
function* sagaFetchMovie(movieId) {
yield call(fetchMovie, movieId);
}
/******************************************************************************/
/******************************* WATCHERS *************************************/
/******************************************************************************/
function* watchFetchMovies() {
while (true) {
yield take(actions.FETCH_MOVIES);
yield fork(sagaFetchMovies);
}
}
function* watchFetchMovie() {
while (true) {
const { movieId } = yield take(actions.FETCH_MOVIE);
yield fork(sagaFetchMovie, movieId);
}
}
export default function* root() {
yield all([fork(watchFetchMovies), fork(watchFetchMovie)]);
}
/***********************************************
***************** UPDATE BELOW *****************
***********************************************/
我告诉你我在哪里派遣我的行动;)
...
class Movie extends Component {
constructor(props) {
super(props);
this.state = { isSlideShowOpened: false };
const movie = props.app.movie.results.filter(e => e.id === Number(props.match.params.movieId));
if (movie.length === 0) {
props.fetchMovie(props.match.params.movieId); // <---- I dispatch here because componentWillMount is deprecated :s
}
}
...
...
class Movies extends PureComponent {
constructor(props) {
super(props);
this.state = {};
if (props.app.movies.results.length === 0) {
props.fetchMovies(); // <---- I dispatch here because componentWillMount is deprecated :s
}
}
...
@loadable/component 服务器端渲染有一个很大的警告 lol
@loadable/component 强制您为每条路线拆分代码,并最终使用回退(下载 js 包时的旋转器)
让我提醒你 @loadable/component 是市场上唯一能够为服务器端渲染做拆分代码的模块 lol
好吧,none 你的故事将由 @loadable/component 等待。我别无选择,这对 google 和 bing 来说并不是那么糟糕,我认为...
例如,我的 React 路由器看起来像这样
import React from 'react';
import loadable from '@loadable/component';
import Loading from './Exception/Loading';
const Home = loadable(() => import('./Home/index'), { fallback: <Loading /> });
const Movies = loadable(() => import('./Movies/index'), { fallback: <Loading /> });
const Movie = loadable(() => import('./Movie/index'), { fallback: <Loading /> });
const Slide1 = loadable(() => import('./Slides/Slide1'), { fallback: <Loading /> });
const Forbidden = loadable(() => import('./Exception/403'));
const NoMatch = loadable(() => import('./Exception/404'));
const ServerDown = loadable(() => import('./Exception/500'));
const indexRoutes = [
{
exact: true,
path: '/',
component: Home
},
{
exact: true,
path: '/last-movie-releases',
component: Movies
},
{
path: '/movie-details/:movieId/:slideshow?',
component: Movie
},
{
path: '/slide1',
component: Slide1
},
{ path: '/403', component: Forbidden },
{ path: '/404', component: NoMatch },
{ path: '/500', component: ServerDown },
{ name: 'NoMatch', component: NoMatch }
];
export default indexRoutes;