我正在创建一个网站来显示一些手机,并设置了一个 API 来从我的数据库传回最新的手机。在我的 componentWillMount 组件中,我正在调度一个操作,然后该操作将获取 API 结果并填充我的商店。然后该组件呈现商店中的内容。
这似乎一切正常,但确实意味着在进行 API 调用时有时不会显示任何内容。
我想知道是否有某种方法可以在服务器上分派(dispatch)操作并将initialState设置为API响应,或者有其他方法将API响应从服务器传递到客户端,以便数据在那里当组件渲染时已经了吗?
这就是我到目前为止所拥有的......
reducer
export function latestPhonesHasErrored(state = false, action) {
switch (action.type) {
case 'LATEST_PHONES_HAS_ERRORED':
return action.latestPhonesHasErrored;
default:
return state;
}
}
export function latestPhonesIsLoading(state = false, action) {
switch (action.type) {
case 'LATEST_PHONES_IS_LOADING':
return action.latestPhonesIsLoading;
default:
return state;
}
}
export function latestPhones(state = [], action) {
switch (action.type) {
case 'LATEST_PHONES_FETCH_DATA_SUCCESS':
return action.latestPhones;
default:
return state;
}
}
行动
export function latestPhonesFetchData() {
return (dispatch) => {
dispatch(latestPhonesIsLoading(true));
fetch('/api/latest-phones/')
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
dispatch(latestPhonesIsLoading(false));
return response;
})
.then((response) => response.json())
.then((results) =>
dispatch(latestPhonesFetchDataSuccess(results)))
.catch(() => dispatch(latestPhonesHasErrored(true)))
}
}
Server.js
const store = createStore(
rootReducer,
initialState,
applyMiddleware(thunk)
);
const router = express.Router();
router.get('/', (req, res) => {
match({routes, location: req.originalUrl}, (err, redirectLocation, renderProps) => {
if(!err) {
const html = this.render(renderProps);
res.render('index', {
content: html,
pageTitle: 'title',
description: 'description',
canonical: 'canonical'
});
} else {
res.status(500).send();
}
});
});
render(renderProps) {
let html = renderToString(
<Provider store={store}>
<RouterContext {...renderProps}/>
</Provider>
);
return html;
}
组件
import {latestPhonesFetchData} from '../../../actions/results-actions';
const mapStateToProps = (state) => {
return {
latestPhones: state.latestPhones
}
};
class Home extends Component {
componentWillMount(){
this.props.latestPhonesFetchData();
}
render(){
/* all component render here*/
}
}
export default connect(mapStateToProps, {latestPhonesFetchData})(Home);
非常感谢任何帮助!
最佳答案
如果您在客户端上渲染 React(您就是这样),则无法在组件渲染之前预加载数据。 @A.Lau 上面的评论是正确的......你最好的选择是在获取数据时渲染加载旋转器或类似的东西。
或者,您可以使用服务器端渲染。这意味着提前渲染 React 并向客户端提供 HTML 文件。通过在服务器上渲染,您可以从数据库中获取所需的数据,并在渲染之前将其作为 Prop 传递给组件。无需 AJAX,并且您无需向客户端显示加载 View 。
关于javascript - Redux 将初始状态设置为 API 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44791325/