开发者问题收集

在 React-Native 中递归调用一个类

2019-02-27
380

我有一个 JSON 对象存储我的菜单。默认情况下,会显示第一个菜单。按下任何菜单项时,我希望显示根据“seq”定义的菜单编号。这是我的 JSON 文件 **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}
      ]
    }
  ]
}

我的 App.js 文件是这样的:

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;

GetMenu 类位于此文件 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>
    );
  }
}

它在 actionOnRow 函数中的 render() 上崩溃

我是否应该以不同的方式执行此操作,而不是以递归方式调用 actionOnRow OnPress?

编辑

一旦我完成此阶段,我想在 actionOnRow() 中添加一个基于“类型”的条件。“M”值将调用下一个菜单,而“L”等其他值将调用外部 JSON 来显示音频列表。

1个回答

首先让我告诉你你的错误是什么。你试图在按下菜单时渲染一个组件。但是你在按下菜单事件中调用渲染函数,但你不能在 onPress 事件中执行此操作。你可以在这里做的是设置一些标志来指示是否渲染内部菜单。在代码中,它将是这样的:

//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)}

或者

你可以将当前菜单存储到你的状态并在按下菜单时更新它。示例代码:

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}
        />

注意:我没有测试所有代码。它们只是例子。如果你不明白什么,请告诉我。

OriHero
2019-02-28