我正在开发一个反应本机图库,名为react-native-chart-wrapper,其中包含barchart,linechart,...等。
我想将几个功能暴露于JS(例如MoveViewTox)
在Android中,Barchartmanager和Linechartmanager继承BarlineChartBaseManager,因此可以将GetCommandSmap和ReceiveCommand放在BarlineChartBaseManager中。
barlinechartbasemanager
protected static final int MOVE_VIEW_TO = 1;
@Nullable
@Override
public Map<String, Integer> getCommandsMap() {
return MapBuilder.of("moveViewToX", MOVE_VIEW_TO_X);
}
@Override
public void receiveCommand(T root, int commandId, @Nullable ReadableArray args) {
switch (commandId) {
case MOVE_VIEW_TO_X:
root.moveViewToX((float) args.getDouble(0));
return;
}
super.receiveCommand(root, commandId, args);
}
但是如何在JS部分中进行操作?
当前,JS代码在下面列表,简单明了。
barchart
const iface = {
name: 'BarChart',
propTypes: {
...BarLineChartBase.propTypes,
drawValueAboveBar: PropTypes.bool,
drawBarShadow: PropTypes.bool,
data: barData
}
};
export default requireNativeComponent('RNBarChart', iface, {
nativeOnly: { onSelect: true }
});
linechart
const iface = {
name: 'LineChart',
propTypes: {
...BarLineChartBase.propTypes,
data: lineData,
}
};
export default requireNativeComponent('RNLineChart', iface, {
nativeOnly: { onSelect: true }
});
我不想在每个图表定义中重复下面的JS代码,并且在React中不建议继承。我该怎么办?
moveViewToX(x) {
UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this),
UIManager.RNBarChart.Commands.moveViewToX,
[x],
);
}
update
我尝试了高阶组合。
移动
export default function Movable(WrappedComponent) {
return class MovableExtended extends React.Component {
move() {
console.log('I extended the wrapped component with functionality move')
}
render() {
return <WrappedComponent move={this.move}/>
}
}
}
突出显示
export default function Highlightable(WrappedComponent) {
return class HighlightableExtended extends React.Component {
highlight() {
console.log('I extended the wrapped component with functionality highlight')
}
render() {
return <WrappedComponent highlight={this.highlight}/>
}
}
}
barlinechart
export default HighlightableChart(MovableChart(BarLineChart))
应用
class App extends Component {
render() {
return (
<BarLineChart ref="chart"/>
);
}
}
this.refs.chart.highlight()
功能正在工作。和 Uncaught TypeError: this.refs.chart.move is not a function
最终解决方案
这是我发现的最简单的模式。易于扩展。
class LineChart extends React.Component {
getNativeComponentName() {
return 'RNLineChart'
}
getNativeComponentRef() {
return this.nativeComponentRef
}
render() {
return <RNLineChart {...this.props} ref={ref => this.nativeComponentRef = ref} />;
}
}
LineChart.propTypes = {
...BarLineChartBase.propTypes,
data: lineData,
};
var RNLineChart = requireNativeComponent('RNLineChart', LineChart, {
nativeOnly: {onSelect: true}
});
export default MoveEnhancer(LineChart);
class BarChart extends React.Component {
getNativeComponentName() {
return 'RNBarChart'
}
getNativeComponentRef() {
return this.nativeComponentRef
}
render() {
return <RNBarChart {...this.props} ref={ref => this.nativeComponentRef = ref} />;
}
}
BarChart.propTypes = {
...BarLineChartBase.propTypes,
drawValueAboveBar: PropTypes.bool,
drawBarShadow: PropTypes.bool,
data: barData
}
var RNBarChart = requireNativeComponent('RNBarChart', BarChart, {
nativeOnly: {onSelect: true}
})
export default MoveEnhancer(BarChart)
export default function MoveEnhancer(Chart) {
return class MovableExtended extends Chart {
moveViewToX(x) {
UIManager.dispatchViewManagerCommand(
findNodeHandle(this.getNativeComponentRef()),
UIManager[this.getNativeComponentName()].Commands.moveViewToX,
[x]
);
}
}
}