Raect
开发中使用context
,会遇到Uncaught ReferenceError: Cannot access 'UserListContext' before initialization
这个问题。
官方文档地址:Context
最初的方案
还原出问题的路径,首先看一下代码路径,一共两个文件
UserList.js
为父组件CmpUserList.js
为子组件
父组件提供数据给子组件。
其次,看一下思路,父组件会创建一个 Context 对象,并导出这个对象,export const UserListContext = React.createContext()
,接着子组件使用CmpUserList.contextType = UserListContext
来使用上下文。
代码如下:
- 父组件
UserList.js
import React from 'react'
import { connect } from 'react-redux'
import CmpUserList from './CmpUserList'
export const UserListContext = React.createContext()
class UserList extends React.Component {
constructor(props) {
super(props)
this.state = {
showPage: 'list', // 要显示的页面 list:列表
props
};
}
changePage = (page, props = {}) => {
this.setState({
showPage: page,
props
})
}
render() {
let showCmp
if (this.state.showPage === 'list') {
showCmp = <CmpUserList
changePage={this.changePage}
{...this.state.props}
/>
}
return (
<UserListContext.Provider value={'214'}>
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'auto' }}>
{showCmp}
</div>
</UserListContext.Provider>
)
}
}
export default connect((store, props) => {
return {
...props
}
})(UserList)
- 子组件
CmpUserList.js
import React from 'react'
import { UserListContext } from './UserList'
// 子组件
class CmpUserList extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div>{this.context}</div>
)
}
}
CmpUserList.contextType = UserListContext
export default CmpUserList
然而,报错了。。。
新方案
解决方案:新建一个js文件创建上下文,并导出给父子组件使用
那么开始吧,
- 新建一个
index.js
文件
// 上下文
import React from 'react';
// 用户列表
export const UserListContext = React.createContext()
- 修改父组件
UserList.js
import React from 'react'
import { connect } from 'react-redux'
import CmpUserList from './CmpUserList'
import { UserListContext } from '../../context/index.js' // 导入这个
export const UserListContext = React.createContext() // 删除这个
class UserList extends React.Component {
constructor(props) {
super(props)
this.state = {
showPage: 'list', // 要显示的页面 list:列表/detail:详情/edit:编辑
props
};
}
changePage = (page, props = {}) => {
this.setState({
showPage: page,
props
})
}
render() {
let showCmp
if (this.state.showPage === 'list') {
showCmp = <CmpUserList
changePage={this.changePage}
{...this.state.props}
/>
}
return (
<UserListContext.Provider value={'214'}>
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'auto' }}>
{showCmp}
</div>
</UserListContext.Provider>
)
}
}
export default connect((store, props) => {
return {
...props
}
})(UserList)
- 修改子组件
CmpUserList.js
import React from 'react'
import { UserListContext } from '../../../context' // 导入这个
import { UserListContext } from './UserList' // 删掉这个
// 子组件
class CmpUserList extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div>{this.context}</div>
)
}
}
CmpUserList.contextType = UserListContext
export default CmpUserList
看页面渲染结果,父组件传入的214
已经在页面渲染出来了。
子组件this.context
来使用上下文。
成功!