问题
I have a JSON object storing my menus. By default the first menu gets displayed. On Press of any menu item I want to display the menu number defined against "seq". Here is my JSON file **menu.json"
{"main":
[
{"mid": 0, "menu":
[
{"id": "1", "title": "Item-1-0", "kw": "Item-1", "type" : "M", "seq" : 1},
{"id": "2", "title": "Item-2", "kw": "Item-2", "type" : "M", "seq" : 2},
{"id": "3", "title": "Item-3", "kw": "Item-3", "type" : "M", "seq" : 3},
{"id": "4", "title": "Item-4", "kw": "Item-4", "type" : "M", "seq" : 4},
{"id": "5", "title": "Item-5", "kw": "Item-5", "type" : "M", "seq" : 5},
{"id": "6", "title": "Item-6", "kw": "Item-6", "type" : "M", "seq" : 6},
{"id": "7", "title": "Item-7", "kw": "Item-7", "type" : "M", "seq" : 7},
{"id": "8", "title": "Item-8", "kw": "Item-8", "type" : "M", "seq" : 8}
]
},
{"mid": 1, "menu":
[
{"id": "1", "title": "Item-1-1", "kw": "Item-1", "type" : "M", "seq" : 8},
{"id": "2", "title": "Item-2", "kw": "Item-2", "type" : "M", "seq" : 9},
{"id": "3", "title": "Item-3", "kw": "Item-3", "type" : "M", "seq" : 10},
{"id": "4", "title": "Item-4", "kw": "Item-4", "type" : "M", "seq" : 11},
{"id": "5", "title": "Item-5", "kw": "Item-5", "type" : "M", "seq" : 12},
{"id": "6", "title": "Item-6", "kw": "Item-6", "type" : "M", "seq" : 13},
{"id": "7", "title": "Item-7", "kw": "Item-7", "type" : "M", "seq" : 14},
{"id": "8", "title": "Item-8", "kw": "Item-8", "type" : "M", "seq" : 15}
]
},
{"mid": 3, "menu":
[
{"id": "1", "title": "Item-1-2", "kw": "Item-1", "type" : "M", "seq" : 16},
{"id": "2", "title": "Item-2", "kw": "Item-2", "type" : "M", "seq" : 17},
{"id": "3", "title": "Item-3", "kw": "Item-3", "type" : "M", "seq" : 18},
{"id": "4", "title": "Item-4", "kw": "Item-4", "type" : "M", "seq" : 19},
{"id": "5", "title": "Item-5", "kw": "Item-5", "type" : "M", "seq" : 20},
{"id": "6", "title": "Item-6", "kw": "Item-6", "type" : "M", "seq" : 21},
{"id": "7", "title": "Item-7", "kw": "Item-7", "type" : "M", "seq" : 22},
{"id": "8", "title": "Item-8", "kw": "Item-8", "type" : "M", "seq" : 23}
]
},
{"mid": 4, "menu":
[
{"id": "1", "title": "Item-1-3", "kw": "Item-1", "type" : "M", "seq" : 24},
{"id": "2", "title": "Item-2", "kw": "Item-2", "type" : "M", "seq" : 25},
{"id": "3", "title": "Item-3", "kw": "Item-3", "type" : "M", "seq" : 26},
{"id": "4", "title": "Item-4", "kw": "Item-4", "type" : "M", "seq" : 27},
{"id": "5", "title": "Item-5", "kw": "Item-5", "type" : "M", "seq" : 28},
{"id": "6", "title": "Item-6", "kw": "Item-6", "type" : "M", "seq" : 29},
{"id": "7", "title": "Item-7", "kw": "Item-7", "type" : "M", "seq" : 30},
{"id": "8", "title": "Item-8", "kw": "Item-8", "type" : "M", "seq" : 31}
]
}
]
}
My App.js file is this:
import React from 'react';
import { Button, View, Text } from 'react-native';
import GetMenu from "./fetchmenu.js";
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
{<GetMenu/>}
</View>
</View>
);
}
}
export default HomeScreen;
And the GetMenu class is in this file fetchmenu.js:
import React from 'react';
import { FlatList, ActivityIndicator, Text, View, TouchableOpacity } from 'react-native';
let dataSource = require('./menu.json');
let menuLevel = 0;
export default class GetMenu extends React.Component {
constructor(props){
super(props);
}
render(){
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={dataSource.main[menuLevel].menu}
renderItem={({item}) =>
(
<TouchableOpacity onPress={ () => actionOnRow(item)}>
<Text>{item.title}, {item.kw}, {item.seq}</Text>
</TouchableOpacity>
)}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
}
function actionOnRow(item) {
menuLevel = item.seq;
alert(item.title + "-" + menuLevel);
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
{<GetMenu/>}
</View>
</View>
);
}
}
It crashes on render() in actionOnRow function
Am I supposed to do it differently instead of recursively calling actionOnRow OnPress?
EDIT
Once I go past this stage I would like to add a condition in actionOnRow() based on "type". An "M" value will call next menu and some other value like "L" will call an external JSON to display a list of Audios.
回答1:
Let me first tell you what is your mistake. You are trying to render a component when the menu is pressed. But your are calling render function inside of menu pressed event, but you cannot do it inside of onPress event. What you could do here is set some flag indicating whether to render inner menu. In code, it would be like this:
//render item of your flatList
<TouchableOpacity onPress={ () => this.setState({renderMenu:true,menuItem:item})}>
<Text>{item.title}, {item.kw}, {item.seq}</Text>
</TouchableOpacity>
//place where you want to render your menu
{this.state.renderMenu&&actionOnRow(this.state.menuItem)}
Alternatively
You could store your current menu to your state and update it when menu is pressed. Example code:
state={currentMenu:dataSource.main[menuLevel].menu}
<FlatList
data={this.state.currentMenu}
renderItem={({item}) =>
(
<TouchableOpacity onPress={ () => this.setState({currentMenu:item})}>
<Text>{item.title}, {item.kw}, {item.seq}</Text>
</TouchableOpacity>
)}
keyExtractor={({id}, index) => id}
/>
NOTE: I did not test all the code. They are just examples. Let me know if you do not understand something.
来源:https://stackoverflow.com/questions/54909733/recursively-calling-a-class-in-react-native