我正在尝试使用react-frontload
实现SSR。该库的作者已在https://hackernoon.com/react-frontload-3ff68988cca上写了一个教程。到目前为止,其他所有内容都说得通了,但是在这个示例的开头,我无法弄清楚getProfileAsync()
中发生了什么(取自上面的教程):
import { frontloadConnect } from 'react-frontload'
// assuming here that getProfileAsync returns a Promise that
// resolves when the profile is loaded into props.boundProfile
const frontload = (props) => (
getProfileAsync(props.username)
)
// all available options, set to the default values
const options = {
noServerRender: false,
onMount: true,
onUpdate: true
}
// just decorate the same underlying component from earlier
const ProfileView =
frontloadConnect(frontload, options)((props) => (
props.profile
? <div>{props.profile.fullName}'s profile</div>
: <div>loading..</div>
))
这是我尝试实现的方法:
const frontload = props => (
getPage('/home').then(page => props.page = page)
);
const ContentRoute =
frontloadConnect(frontload)(props => (
props.page
? <div>Content goes here</div>
: <div>Loading...</div>
));
export default ContentRoute;
我没有得到的是如何将page
中的frontload()
传递到props
中的frontloadConnect()
,这是我应该做的。
我的getPage()
通过axios
返回一个承诺:
const getPage = route => axios
.get('...query...')
.then(res => res.data.data.pages[0]);
我想它可以正常工作,因为getPage('/home').then(page => console.log(page))
记录了我要寻找的对象。
非常感谢!
EDIT1:我得到的错误是:Uncaught (in promise) TypeError: Cannot add property page, object is not extensible
。
答案 0 :(得分:1)
我是react-frontload
的作者。
我不明白的是如何将frontload()中的页面传递给frontloadConnect()中的道具
您不能,至少不能直接。您的frontload函数应该返回一个Promise<void>
并且不应以任何方式修改(或变异)props
-它不会将prop传递给基础组件。
相反,它应该执行异步请求,然后使用您选择的状态管理解决方案更新状态。这可以是redux,也可以像具有react组件状态的父组件一样简单。当然,状态管理代码需要包装在一个函数中,该函数作为道具传递到更上层的链中,然后可以从frontload函数访问。
为了用代码说明,这是您使用redux的示例(为简化起见,省略了减速器等)
const mapState = (state) => ({
page: state.page
})
const mapDispatch = (dispatch) => ({
updatePage: () => (
getPage('/home')
.then(page => dispatch({ type: 'UPDATE_PAGE', page }))
)
})
const frontload = props => (
// state update left to redux connected function
// which is added to props further up the chain
// i.e. props are not directly modified in the frontload function
props.updatePage()
);
const ContentRoute =
connect(mapState, mapDispatch)(
frontloadConnect(frontload)(props => (
props.page // page is connected from redux state
? <div>Content goes here</div>
: <div>Loading...</div>
)));
export default ContentRoute;
为什么?因为这种方式react-frontload
不需要关心异步状态/道具管理,而可以将其留给您已经在使用的状态管理解决方案。