React-Native Обрабатывает огромное количество входов в аккордеоне одним щелчком мыши из родительского компонента. - PullRequest
0 голосов
/ 13 февраля 2020

Я новичок в мире React. В моем проекте у меня есть другое количество пользовательских аккордеонных объектов, у которых есть плоский список ввода текста. Как я могу обработать такую ​​систему ввода одним нажатием кнопки от родителя объектов аккордеона. Я хочу иметь одну кнопку, которая собирает все текущие данные и затем заканчивает ее на сервере или любых других соответствующих страницах. (Я использую функциональный макет с отслеживанием состояния.)

Спасибо за любой ответ, Bests

Вы можете увидеть макет здесь!

Вы может увидеть аккордеон. js ниже:

    import React, { Component, useState, useEffect} from 'react';
    import { View, TouchableOpacity, FlatList, StyleSheet, TextInput } from "react-native";
    //import { Colors } from './Colors';

    import { theme } from "../constants";
    import Text from "./Text";

    import Icon from "react-native-vector-icons/MaterialIcons";
    import { ScrollView } from 'react-native-gesture-handler';
    const Colors = {
      PRIMARY: '#1abc9c',

      WHITE: '#ffffff',
      LIGHTGREEN: '#BABABA',
      GREEN: '#0da935',


      GRAY: '#f7f7f7',
      LIGHTGRAY: '#C7C7C7',
      DARKGRAY: '#5E5E5E',
      CGRAY: '#ececec',
      OFFLINE_GRAY: '#535353'
    }


    export default function Accordion (props)  {


      const [data, setData] = useState(props.data)

      const [expanded, setExpanded] = useState(false)

      const onClick = (index) => {
        const temp = data.slice()
        temp[index].value = !temp[index].value
        console.log(temp)
        setData(temp)
      }


      const toggleExpand = (section) => {
        //this.setState({ expanded: !this.state.expanded )

        setExpanded(prev_state => !prev_state)
        props.fromparentonClick(expanded)

        }

      useEffect(() => {
          console.log('will unmount')

      }, [expanded]);



        return (

          <View>
            <TouchableOpacity
              style={styles.row}
              onPress={() => toggleExpand()}
            >
              <Text style={[styles.title, styles.font]}>
                {props.title}
              </Text>
              <Icon
                name={
                    expanded
                    ? "keyboard-arrow-up" //this is condinational  ternary operator rendering :)
                    : "keyboard-arrow-down"
                }
                size={30}
                color={Colors.DARKGRAY}
              />
            </TouchableOpacity>
            <View style={styles.parentHr} />
            { expanded && ( //this is short circuit operator
              <View style={{}}>
                <FlatList
                  data={data}
                  numColumns={1}
                  scrollEnabled={true}
                  renderItem={({ item, index }) => (
                    <View styles={styles.deneme}>
                      <Text style={[styles.font, styles.itemInActive]}>
                        {item.key}
                      </Text>
                      <TouchableOpacity
                        style={[
                          styles.childRow,
                          styles.button,
                          item.value ? styles.btnInActive : styles.btnActive
                        ]}
                        onPress={() => onClick(index)}
                      >

                        <Icon
                          name={"check-circle"}
                          size={24}
                          color={item.value ? Colors.LIGHTGRAY : Colors.GREEN}
                        />
                        {/* <Text style={[styles.font, styles.itemInActive]}>
                              {item.key}
                            </Text>*/}

                        <TextInput
                          style={
                            styles.text_input
                          }
                          blurOnSubmit
                          placeholder="input1"
                          placeholderTextColor="#60605e"
                          numeric
                          keyboardType={"numeric"}
                          maxLength={3}
                        />

                        <TextInput
                          style={
                            styles.text_input
                          }
                          blurOnSubmit
                          placeholder="input2"
                          placeholderTextColor="#60605e"
                          numeric
                          keyboardType={"numeric"}
                          maxLength={3}
                        />

                        <TextInput
                          style={
                            styles.text_input
                          }
                          blurOnSubmit
                          placeholder="input3"
                          placeholderTextColor="#60605e"
                          numeric
                          keyboardType={"numeric"}
                          maxLength={3}
                        />

                      </TouchableOpacity>


                      <View style={styles.childHr} />
                    </View>
                  )}
                />
              </View>
            )}
          </View>
        );

                        }

    const styles = StyleSheet.create({
      container: {
        justifyContent: 'center',
        alignItems: 'center'
      },
      font: {
        // fontFamily: Fonts.bold,
      },
      button: {
        width: '100%',
        height: 54,
        alignItems: 'center',
        paddingLeft: 35,
        paddingRight: 35,
        fontSize: 12,
      },
      title: {
        fontSize: 14,
        fontWeight: 'bold',
        color: Colors.DARKGRAY,
      },
      itemActive: {
        fontSize: 12,
        color: Colors.GREEN,
      },
      itemInActive: {
        fontSize: 12,
        color: Colors.DARKGRAY,
      },
      btnActive: {
        borderColor: Colors.GREEN,
      },
      btnInActive: {
        borderColor: Colors.DARKGRAY,
      },
      row: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        height: 56,
        paddingLeft: 25,
        paddingRight: 18,
        alignItems: 'center',
        backgroundColor: Colors.CGRAY,
      },
      childRow: {
        flexDirection: 'row',
        justifyContent: 'space-around',
        backgroundColor: Colors.GRAY,
      },
      parentHr: {
        height: 1,
        color: Colors.WHITE,
        width: '100%'
      },
      childHr: {
        height: 1,
        backgroundColor: Colors.LIGHTGRAY,
        width: '100%',
      },
      colorActive: {
        borderColor: Colors.GREEN,
      },
      colorInActive: {
        borderColor: Colors.DARKGRAY,
      },
      text_input: {

        width: 80,
        backgroundColor: "#dde8c9",
        padding: 10,
        textAlign: 'center'

      },
      deneme: {
        flexDirection: 'column',
        textAlign: 'center',
        justifyContent: 'center',




      }

    });

Вы можете увидеть родительский компонент ниже:

    import * as WebBrowser from 'expo-web-browser';
    import React, { Component,useState } from 'react';

    import {
      Image,
      Platform,
      ScrollView,
      StyleSheet,
      Text,
      TouchableOpacity,
      View,
    } from 'react-native';

    import { Button, Block, Input,Accordion ,Header} from "../components";
    import { theme } from "../constants";
    //import {CATEGORIES} from "../Data/dersler";
    import SwitchSelector from "react-native-switch-selector";

    import { MonoText } from '../components/StyledText';
    import 'core-js/es6/symbol'; import 'core-js/fn/symbol/iterator';


      export default function HomeScreen (props) {



                      const options = [
                          { label: "x", value: "1" },
                          { label: "y", value: "2" }
                        ]


                        const initial_state = {

                          courses: [
                            {
                              key: "c1",
                              title: "ss",
                              data: [
                                { key: "dd", value: "false" },
                                { key: "ff", value: "false" },
                                { key: "gg ", value: "false" }
                              ]
                            },
                            {
                              key: "c2",
                              title: "ss2",
                              data: [
                                { key: "dd", value: "false" },
                                { key: "ff", value: "false" },
                                { key: "gg", value: "false" },
                                { key: "cc", value: "false" }
                              ]
                            },

                          ],





                        }



                        const second_state = {

                          courses: [
                            {
                              key: "c1",
                              title: "dd",
                              data: [
                                { key: "cc", value: "false" },
                                { key: "dd", value: "false" },
                                { key: "ff ", value: "false" }
                              ]
                            },

                          ]




                        }











    const [exam, setExam] = useState(initial_state)
    const [onlineAcc, setonlineAcc] = useState(false)
    const [activeSession, setactiveSession] = useState(0)

    const controlAccordions = (arg) => {

      setonlineAcc(prev_state => !prev_state)

      //console.log(onlineAcc)
      console.log(arg)

      if(arg){
        setactiveSession(prev_state => prev_state -1 )

      }

      else {

        setactiveSession(prev_state => prev_state + 1)

      }
      console.log(activeSession)


    }

    const renderAccordians = () => {

          let items = [];
          //console.log(`Call onPress with value: ${ this.state}`);
          //console.log(exam.courses);

      return exam.courses.map(ex => (<Accordion active={activeSession} fromparentonClick={controlAccordions} title={ex.title} data={ex.data} key={ex.key} /> ))



          //return items;
        }




     return (
                          <View style={styles.container}>
                            <Header title="Anasayfa" />

                            <SwitchSelector
                              options={options}
                              initial={1}
                              buttonColor={theme.colors.gray2}

                              onPress={value => {

                              if( value== 1)
                              {setExam (second_state)}

                              else {

                                setExam(initial_state)
                              }

                              console.log(value)


                              }}
                            />
                            <ScrollView style={styles.container}>
                              {renderAccordians()}
                            </ScrollView>
                          </View>
                        );




      }



    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#fff',
      },
      developmentModeText: {
        marginBottom: 20,
        color: 'rgba(0,0,0,0.4)',
        fontSize: 14,
        lineHeight: 19,
        textAlign: 'center',
      },
      contentContainer: {
        paddingTop: 30,
      },
      welcomeContainer: {
        alignItems: 'center',
        marginTop: 10,
        marginBottom: 20,
      },
      welcomeImage: {
        width: 100,
        height: 80,
        resizeMode: 'contain',
        marginTop: 3,
        marginLeft: -10,
      },
      getStartedContainer: {
        alignItems: 'center',
        marginHorizontal: 50,
      },
      homeScreenFilename: {
        marginVertical: 7,
      },
      codeHighlightText: {
        color: 'rgba(96,100,109, 0.8)',
      },
      codeHighlightContainer: {
        backgroundColor: 'rgba(0,0,0,0.05)',
        borderRadius: 3,
        paddingHorizontal: 4,
      },
      getStartedText: {
        fontSize: 17,
        color: 'rgba(96,100,109, 1)',
        lineHeight: 24,
        textAlign: 'center',
      },
      tabBarInfoContainer: {
        position: 'absolute',
        bottom: 0,
        left: 0,
        right: 0,
        ...Platform.select({
          ios: {
            shadowColor: 'black',
            shadowOffset: { width: 0, height: -3 },
            shadowOpacity: 0.1,
            shadowRadius: 3,
          },
          android: {
            elevation: 20,
          },
        }),
        alignItems: 'center',
        backgroundColor: '#fbfbfb',
        paddingVertical: 20,
      },
      tabBarInfoText: {
        fontSize: 17,
        color: 'rgba(96,100,109, 1)',
        textAlign: 'center',
      },
      navigationFilename: {
        marginTop: 5,
      },
      helpContainer: {
        marginTop: 15,
        alignItems: 'center',
      },
      helpLink: {
        paddingVertical: 15,
      },
      helpLinkText: {
        fontSize: 14,
        color: '#2e78b7',
      },
    });

1 Ответ

0 голосов
/ 13 февраля 2020

вам придется отслеживать данные аккордеонов в родительском классе

let accordionData = [];

const addAccordionData = data => {
   accordionData.push(data);
}  

const renderAccordians = () => {

    let items = [];
          //console.log(`Call onPress with value: ${ this.state}`);
          //console.log(exam.courses);

      return exam
        .courses.map(ex => (
            <Accordion 
             active={activeSession} 
             fromparentonClick= {controlAccordions} 
             title={ex.title} 
             data={ex.data} 
            onAccordianDataSet={addAccordianData} // add this line <====
             key={ex.key} /> ))



          //return items;
}

в компоненте accordion , для этого

// in the **accordion ** component do this
const onClick = (index) => {
        const temp = data.slice()
        temp[index].value = !temp[index].value
        console.log(temp)
        setData(temp);
       // add this line
        props.onAccordianDataSet(temp); // now the answer will be in the parents
      }

и у вас может быть кнопка в родительском элементе, которая вызывает такую ​​функцию

const submitDataToDatabase = () => {
   if(accordionData.length === 0) {
       alert("answer every question"); 
       return;
   }

   submit data to database storage
}
...