使用module.exports公开React类实例

时间:2018-03-05 15:53:28

标签: javascript reactjs react-router

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

//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")

代码笔:https://codepen.io/Stefvw93/pen/bLyyNG?editors=0010

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

的操作来导出此实例。

1 个答案:

答案 0 :(得分:0)

由于您无法声明任何动态导出,因此导出pushpop的唯一方法是首先导出某种可变容器对象,然后再修改它。例如,立即导出一个空对象,并在构造函数中设置其pushpop属性。

//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,因为:

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

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