我对Nashorn和React-redux有奇怪的行为。
首先,我有一个非常简单的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
处理功能将不起作用。我在这里做错什么以及如何使它起作用?
更新:
我发现问题出在混入批处理文件中。如果将文件放到文件中,而我只想评估React组件(JS,而不是JSX)和不带任何库的renderServer函数,Nashorn可以找到renderServer函数并调用它。
但是所有教程都说Nashorn非常适合理解批处理文件。
所以我真的不明白这可能是什么问题。
最佳答案
由于您可能正在使用webpack,因此var renderServer最终将成为webpack函数中的局部变量。
global.renderServer = ....应该可以工作