我的应用程序正在使用服务器渲染,在使用名为react dragula 的dragula库的react扩展时遇到了一个问题
这里的问题在于
import Dragula from 'react-dragula';
由于某种原因,这使用了document
,因此在服务器端呈现过程中会导致错误,因为文档不存在,因此我需要一种方法,只在document
可用时才包括它,这样我就可以开始使用它。
没有办法有条件地import
某事,但有办法绕过它。我通常处理这类问题的方法是创建单独的构建供服务器和客户端使用,并在构建过程中使用process.env-vars来区分两者。它不需要对代码进行太多修改,但通过这种方式可以在某种程度上模拟依赖关系。
例如,你可以做这样的事情:
import Dragula from './my-dragula-wrapper'
在包装文件中,使用CommonJS require
返回正确的模块:
/* my-dragula-wrapper.js */
if(process.env.SOME_VAR === 'server'){
module.exports = function(){}; // Or something, it's not going to be used anyway
} else {
module.exports = require('react-dragula');
}
然后,只需在构建过程中设置正确的process.env.SOME_VAR值,无论是Gulp还是Grunt,或者本周最酷的东西。
gulp.task('env:server', function(){
return process.env.SOME_VAR = 'server';
});
gulp.task('env:client', function(){
return process.env.SOME_VAR = 'client';
});
将其与Browserify的Envify转换或类似操作一起使用。你应该表现得很好。
我不知道这是否是一个好的做法。但你可以做到,
componentDidMount(){
var Dragula = require('Dragula')
}
这只会在客户端导入dragula。从未从服务器端运行完成装载的组件
您必须在渲染函数中包含检查,以查看德拉古拉是否存在。但这样的事情会奏效的。我刚刚做到了。
我做的是
var something // so that it has scope in all functions
componentDidMount(){
something = require('something')
this.setState({somethingExists: true})
}
render(){
return(
<div> {this.state.somethingExists ? <something> : null } </div>
)
}
添加到dannyjolie建议中。
你可以使用try-catch而不是设置在gullow/grumnt 中
try {
if(window)
module.exports = require('react-dragula');
}
catch(ex)
{
module.exports = function(){};
}