【发布时间】:2016-03-08 14:23:35
【问题描述】:
我对使用 React-redux 的 Nashorn 有奇怪的行为。 首先,我有一个非常简单的 javascript,它在部署之前被 babelified(我把 JSX 放在这里,因为结果 babelified 文件很大):
var React = require('react');
var ReactDOM = require('react-dom');
var connect = require('react-redux').connect;
var Link = require('react-router').Link;
function mapStateToProps(state) {
console.log("mapStateToProps ", state);
return {options: state.options};
};
var IndexContainer = React.createClass({
render: function () {
console.log(this.props.options);
return (
<div>
<Link to="r">Link!</Link>
</div>
);
}
});
var Index = connect(mapStateToProps)(IndexContainer);
var renderServer = function (data) {
var data = Java.from(data);
return React.renderToString(
React.createElement(Index, {data: data})
);
};
第二,我有Java代码:
@Component
@SuppressWarnings("restriction")
public class ReactRenderer {
private ThreadLocal<NashornScriptEngine> engineHolder = new ThreadLocal<NashornScriptEngine>() {
@Override
protected NashornScriptEngine initialValue() {
NashornScriptEngine nashornScriptEngine = (NashornScriptEngine) new ScriptEngineManager()
.getEngineByName("nashorn");
try {
nashornScriptEngine.eval(read("static/nashorn-polyfill.js"));
nashornScriptEngine.eval(read("/WEB-INF/resources/js/main.js"));
} catch (ScriptException e) {
throw new RuntimeException(e);
}
return nashornScriptEngine;
}
};
private Reader read(String path) {
InputStream in = getClass().getClassLoader().getResourceAsStream(path);
return new InputStreamReader(in);
}
public String render(List<Object> objects) {
try {
Object html = engineHolder.get().invokeFunction("renderServer", objects);
return String.valueOf(html);
} catch (Exception e) {
throw new IllegalStateException("failed to render react component", e);
}
}
}
当我在 java 中调用 render(objects) 时,我得到:
java.lang.NoSuchMethodException: No such function renderServer
jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:204)
jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:383)
jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:190)
如果我删除
function mapStateToProps(state) {
console.log("mapStateToProps ", state);
return {options: state.options};
};
它确实找到了 renderServer 函数,但是由于那里没有 mapStateToProps 而无法评估,并且根据 redux 的说法,tutorial 应该被渲染为使用所有道具、Provider 等将整个事物串起来,而不仅仅是React component,否则使用this.store.dispatch 的处理函数将不起作用。
我在这里做错了什么以及如何使它起作用?
更新: 我发现问题出在 babelified 批处理文件上。如果我将文件放入我只想评估 React 组件(JS,而不是 JSX)和 renderServer 函数而没有任何库,Nashorn 能够找到 renderServer 函数并调用它。 但是所有的教程都说 Nashorn 在理解批处理文件方面是完美的。 所以我真的不明白问题出在哪里。
【问题讨论】:
-
您使用的是什么 JDK/Nashorn 版本?在早期的 JDK8 版本中,使用 Nashorn 运行 React 存在问题。也许尝试使用 early access snapshot 的最新更新版本
-
@HannesWallnöfer 我用的是8u65 Oracle,没发现这种错误。
-
8u65 应该没问题。 “批处理文件”是什么意思? Nashorn 只能处理 JS 文件。
-
我的意思是它是一个包含所有库代码的已处理文件,而不是“require”或“import”语句。对不起,我是一个JS新手,可能我混淆了那个文件的一个词。
标签: javascript java reactjs nashorn redux