如何向 React 的 props 添加数据
How to add data to React's props
我正在尝试使用 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;
我不明白的是如何将 frontload()
中的 page
传递给 frontloadConnect()
中的 props
,这就是我想的应该做的。
我的 getPage()
returns 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
.
我是 react-frontload
的作者。
What I don't get is how to pass page in frontload() to props in frontloadConnect()
你不能,至少不能直接。你的 frontload 函数应该 return a Promise<void>
并且不应该以任何方式修改(或变异)props
- 它不会 'pass on' 支持底层组件。
相反,它应该执行异步请求,然后使用您选择的状态管理解决方案更新状态。这可以是 redux,也可以像具有 React 组件状态的父组件一样简单。当然,状态管理代码需要包装在一个函数中,该函数作为 prop 进一步向上传递,然后可以从 frontload 函数访问。
为了用代码进行说明,这是您使用 redux 的示例(省略了 reducer 等以保持简短)
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
不需要关心异步 state/props 管理,可以将其留给您已经在使用的状态管理解决方案。
我正在尝试使用 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;
我不明白的是如何将 frontload()
中的 page
传递给 frontloadConnect()
中的 props
,这就是我想的应该做的。
我的 getPage()
returns 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
.
我是 react-frontload
的作者。
What I don't get is how to pass page in frontload() to props in frontloadConnect()
你不能,至少不能直接。你的 frontload 函数应该 return a Promise<void>
并且不应该以任何方式修改(或变异)props
- 它不会 'pass on' 支持底层组件。
相反,它应该执行异步请求,然后使用您选择的状态管理解决方案更新状态。这可以是 redux,也可以像具有 React 组件状态的父组件一样简单。当然,状态管理代码需要包装在一个函数中,该函数作为 prop 进一步向上传递,然后可以从 frontload 函数访问。
为了用代码进行说明,这是您使用 redux 的示例(省略了 reducer 等以保持简短)
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
不需要关心异步 state/props 管理,可以将其留给您已经在使用的状态管理解决方案。