使用module.exports公开React类实例

问题描述 投票:0回答:1

我知道标题可能有点令人困惑。这是一个代码示例:

//First.js
export default class First extends React.Component {
  constructor(props) {
    super(props);

    module.exports.push = route => {
       this.refs.router.push(route)
    }

    module.exports.pop = () => {
       this.refs.router.pop()
    }
  }

  render() {
    return <Router ref="router"/>
  }
}

然后

//second.js
import { push, pop } from "first.js"

//class instantiation and other code
push("myRoute")

Codepen:qazxsw poi

目的是避免使用react-router中的withRouter函数。因此,请从react-router的browserRouter组件的单个实例公开推/弹历史记录功能。它的工作原理是创建对路由器实例的引用(ref =“router”),然后通过执行类似module.exports.push = this.refs.router.push的操作来导出此实例。

javascript reactjs react-router
1个回答
0
投票

由于你不能声明任何动态导出,导出https://codepen.io/Stefvw93/pen/bLyyNG?editors=0010push的唯一方法是首先导出某种可变容器对象,然后再修改它。例如,立即导出一个空对象,并在构造函数中设置其poppush属性。

pop

然后

//First.js
export const router = {};

export default class First extends React.Component {
  constructor(props) {
    super(props);

    router.push = route => {
       this.refs.router.push(route)
    };

    router.pop = () => {
       this.refs.router.pop()
    };
  }

  render() {
    return <Router ref="router"/>
  }
}

但这样做有很大的缺点:

  • 你将最终使用最后渲染的路由器实例
  • 如果这样的实例已经存在,则不会检查
  • 您不能使用相同模式的多个路由器

我更喜欢明确并在任何需要路由器的地方写//second.js import { router } from "first.js" //class instantiation and other code router.push("myRoute") ,因为:

  • 它不受竞争条件的影响 - 你要么有路由器要么你没有,在这种情况下你得到一个很好的错误日志
  • 它清楚地传达了你的意图,并且存在关于withRouter的文档
  • 采用着名而优雅的HoC图案
  • 允许您拥有多个路由器

长话短说,可变的全球状态很糟糕,只是不要这样做。

© www.soinside.com 2019 - 2024. All rights reserved.