Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop-down is too slow in my case . It takes too long . #88

Open
moussasarr opened this issue Feb 25, 2018 · 14 comments
Open

Drop-down is too slow in my case . It takes too long . #88

moussasarr opened this issue Feb 25, 2018 · 14 comments

Comments

@moussasarr
Copy link

My drop-down is pretty slow. It especially takes a long time if I try to change my major. Or anything dealing with adding or editing a major . I really need to make adding or editing a major much faster. I am not sure the reason why editing or adding a major is taking too long with react-native-material-dropdown. And I am not sure about how to go at making adding and editing a major much faster. So I am posting the entire component and I am commenting parts that deal with adding or editing a major. I Here is the entire component code:

import React from 'react';
import PropTypes from 'prop-types';
import { View, ScrollView, Text, TouchableOpacity } from 'react-native';
import { connect } from 'react-redux';
import { compose, withStateHandlers } from 'recompose';
import { Dropdown } from 'react-native-material-dropdown';
import { Icon } from 'react-native-material-ui';
import R from 'ramda';
import { ConnectivityRenderer } from 'react-native-offline';
import NetworkConnectivity from '../error/NetworkConnectivity';
import { toArray } from '../selectors';
import { Container, Switch, SwitchOption } from './common';
import { editStudent } from '../actions';

const propTypes = {
  toolbar: PropTypes.elem,
  loading: PropTypes.bool,
  university: PropTypes.shape({
  id: PropTypes.string,
  name: PropTypes.string,
  }),
  universities: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string,
      name: PropTypes.string,
    })
  ),
  degrees: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string,
      name: PropTypes.string,
    })
  ),
  studentDegrees: PropTypes.arrayOf(
    PropTypes.shape({
      index: PropTypes.number,
      track: PropTypes.string,
    })
  ),
  errors: PropTypes.shape({
    university: PropTypes.string,
    degree: PropTypes.string,
  }),
  year: PropTypes.string,
  onUniversityChange: PropTypes.func,
  onTermChange: PropTypes.func,
  onDegreeChange: PropTypes.func,
  onYearChange: PropTypes.func,
  onTrackChange: PropTypes.func,
  onAddDegree: PropTypes.func,
  onDone: PropTypes.func,
};

const contextTypes = {
  uiTheme: PropTypes.object.isRequired,
};

const validate = state => {
  const result = {};

  if (!state.university.id) {
    result.university = 'You should select an university';
  }

  return result;
};

const enhance = compose(
  connect(
    ({ user, universities, degrees }) => ({
      studentId: user.id,
      user,
      universities: toArray(universities),
      degrees: toArray(degrees),
    }),
    { editStudent }
  ),
  withStateHandlers(
    props => {
      return {
        university: props.user.university || {},
        year: props.user.academicClass || 'freshman',
        studentDegrees: R.isEmpty(props.degrees)
          ? []
          : R.isEmpty(props.user.studentDegrees)
            ? [{ degree_id: props.degrees[0].id, track: 'Major' }]
            : R.values(props.user.studentDegrees),
        errors: {},
       };
    },
    {
      onUniversityChange: () => (value, index, data) => ({
        university: data[index],
       }),
      onYearChange: () => year => ({ year }),
      onTrackChange: state => ({ idx, track }) => ({
        studentDegrees: R.update(
          idx,
          R.assoc('track', track, state.studentDegrees[idx]),
          state.studentDegrees
        ),
      }),
      


      // Fucntion dealing with degree change

      onDegreeChange: (state, props) => ({ idx, index }) => ({
         studentDegrees: R.update(
          idx,
          R.assoc(
            'degree_id',
            props.degrees[index].id,
            state.studentDegrees[idx]
          ),
          state.studentDegrees
        ),
      }),
      

    // Function dealing with degree adding

    onAddDegree: (state, props) => () => ({
        studentDegrees: R.append(
          {
            degree_id: props.degrees[0].id,
            track: 'Major',
          },
          state.studentDegrees
        ),
      }),
      onRemoveDegree: state => idx => ({
        studentDegrees: [
          ...state.studentDegrees.slice(0, idx),
          ...state.studentDegrees.slice(idx + 1),
        ],
      }),
  

      // When the user is done with settings.
      // This function communicates with the back end to save things in the remote database
      onDone: (state, { studentId, editStudent }) => () => {
      const errors = validate(state);
        if (Object.keys(errors).length !== 0) {
          return { errors };
        }

        editStudent(
          studentId,
          state.year,
          state.university.id,
          state.studentDegrees
        );
      },
    }
  )
);




// The Settings Component 
  const FormUserSettings = (props, context) => {
  const styles = getStyles(props, context);

  return (
    <ConnectivityRenderer>
      {isConnected => (
        isConnected ? (
          <Container>
            {React.cloneElement(props.toolbar, {
              onRightElementPress: props.onDone,
            })}
            <ScrollView style={styles.container}>
              <Text
                style={[
                  styles.title,
                  props.errors.university ? styles.titleError : {},
                ]}
              >
                University
              </Text>
           
          // Selecting a university
              <Dropdown
                label="Select university..."
                data={props.universities.map(u => ({ id: u.id, value: u.name }))}
                onChangeText={props.onUniversityChange}
                value={props.university.name}
              />
              {props.errors.university &&
                <Text style={styles.errorMessage}>
                  {props.errors.university}
                </Text>}
              <View style={{ height: 16 }} />
                <Text style={styles.title}>Current Year</Text>
               <View style={{ height: 8 }} />
              <Switch
                value={props.year}
                onChange={props.onYearChange}
                selectedColor={styles.switchSelectedColor}
                unselectedColor={styles.switchUnselectedColor}
               >
                <SwitchOption text="Freshman" value="freshman" />
                <SwitchOption text="Sophomore" value="sophomore" />
                <SwitchOption text="Junior" value="junior" />
                <SwitchOption text="Senior" value="senior" />
                </Switch>
               <View style={{ height: 16 }} />
               <Text
                style={[styles.title, props.errors.degree ? styles.titleError : {}]}
              >
            Major / Minors
          </Text>
          {!R.isEmpty(props.degrees) &&
            props.studentDegrees.map((sd, idx) => {
              const degree = R.find(R.propEq('id', sd.degree_id), props.degrees);

              return (
                <View
                  key={`sd-${idx}`}
                  style={{ flex: 1, height: 96, marginTop: 24 }}
                >
                  <View
                    style={{
                      flex: 1,
                      flexDirection: 'row',
                      alignItems: 'flex-end',
                    }}
                  >
                    <View style={{ flex: 1 }}>
                      <Dropdown
                        style={{ flex: 1 }}
                        label="Select degree..."
                        data={props.degrees.map(d => ({
                          id: d.id,
                          value: d.name,
                        }))}
                        onChangeText={(value, index) =>
                          props.onDegreeChange({ idx, index })}
                        value={degree ? degree.name : ''}
                      />
                    </View>
                    {props.studentDegrees.length !== 1 &&
                      <TouchableOpacity
                        style={{ marginBottom: 8, paddingLeft: 24 }}
                        onPress={() => props.onRemoveDegree(idx)}
                      >
                        <Icon name="delete" size={24} />
                      </TouchableOpacity>}
                  </View>
                  <Switch
                    value={sd.track}
                    onChange={track => props.onTrackChange({ idx, track })}
                    selectedColor={styles.switchSelectedColor}
                    unselectedColor={styles.switchUnselectedColor}
                  >
                    <SwitchOption text="Major" value="Major" />
                    <SwitchOption text="Minor" value="Minor" />
                    <SwitchOption text="Certificate" value="Cert" />
                  </Switch>
                </View>
              );
            })}
          <TouchableOpacity style={{ padding: 10 }} onPress={props.onAddDegree}>
            <Text style={styles.addDegreeText}>+ Degree</Text>
          </TouchableOpacity>
        </ScrollView>
      </Container>
    ) : (
      <Container>
        {React.cloneElement(props.toolbar, {
          onRightElementPress: props.onDone,
        })}
        <NetworkConnectivity />
        <ScrollView style={styles.container}>
          <Text
            style={[
              styles.titleDisabled,
              props.errors.university ? styles.titleError : {},
            ]}
          >
            University
          </Text>
          <Dropdown
            label=""
            data={props.universities.map(u => ({ id: u.id, value: u.name }))}
            onChangeText={props.onUniversityChange}
            value={props.university.name}
            disabled={true}
            editable={false}
          />
          {props.errors.university &&
            <Text style={styles.errorMessage}>
              {props.errors.university}
            </Text>}
          <View style={{ height: 16 }} />
          <Text style={styles.titleDisabled}>Current Year</Text>
          <View style={{ height: 8 }} />
          <Switch
            value={props.year}
            onChange={props.onYearChange}
            selectedColor={styles.disabledSwitchSelectedColor}
            unselectedColor={styles.switchUnselectedColor}
          >
            <SwitchOption text="Freshman" value="freshman" />
            <SwitchOption text="Sophomore" value="sophomore" />
            <SwitchOption text="Junior" value="junior" />
            <SwitchOption text="Senior" value="senior" />
          </Switch>
          <View style={{ height: 16 }} />
          <Text
            style={[styles.titleDisabled, props.errors.degree ? styles.titleError : {}]}
          >
            Major / Minors
          </Text>
          
          // The problem of slowness starts here
          // I feel like something here should be improved
          {!R.isEmpty(props.degrees) &&
            props.studentDegrees.map((sd, idx) => {
              const degree = R.find(R.propEq('id', sd.degree_id), props.degrees);

                  return (
                    <View
                      key={`sd-${idx}`}
                      style={{ flex: 1, height: 96, marginTop: 24 }}
                    >
                      <View
                        style={{
                          flex: 1,
                          flexDirection: 'row',
                          alignItems: 'flex-end',
                        }}
                      >
                        <View style={{ flex: 1 }}>
                          <Dropdown
                            style={{ flex: 1 }}
                            label="Select degree..."
                            data={props.degrees.map(d => ({
                              id: d.id,
                              value: d.name,
                            }))}
                            disabled={true}
                            editable={false}
                            onChangeText={(value, index) =>
                              props.onDegreeChange({ idx, index })}
                            value={degree ? degree.name : ''}
                          />
                        </View>
                      </View>
                      <Switch
                        value={sd.track}
                         onChange={track => props.onTrackChange({ idx, track })}
                        selectedColor={styles.disabledSwitchSelectedColor}
                        unselectedColor={styles.switchUnselectedColor}
                      >
                        <SwitchOption text="Major" value="Major" />
                        <SwitchOption text="Minor" value="Minor" />
                        <SwitchOption text="Certificate" value="Cert" />
                      </Switch>
                    </View>
                  );
                })}
              <TouchableOpacity disabled={true} style={{ padding: 10 }} onPress={props.onAddDegree} disabled={true}>
                <Text style={styles.addDegreeTextDisabled}>+ Degree</Text>
              </TouchableOpacity>
            </ScrollView>
          </Container>
        )
      )}
    </ConnectivityRenderer>
  );
};



FormUserSettings.contextTypes = contextTypes;
FormUserSettings.propTypes = propTypes;

export default enhance(FormUserSettings);
@chauhanshubham-dev
Copy link

+1

4 similar comments
@mingca
Copy link

mingca commented Mar 6, 2018

+1

@Thanmai-C
Copy link

+1

@kmistry98
Copy link

+1

@sathishmscict
Copy link

+1

@danisbubblesdad
Copy link

Does using the animationDuration property at a lower number of milliseconds not help? The default is 255.

@moussasarr
Copy link
Author

No I solved it. react-native-matrerial-dropdown was using a ScrollView in versions before 8.0.0. So it was extremely slow for large lists like in my case. I just had to upgrade to the lastest version, where they use a FlatList instead, which is much faster.

@NdaJunior
Copy link

NdaJunior commented May 30, 2018

I've upgraded to version 0.11.1 and the dropdown is still super slow...anyone else experiencing this?

@Ryeru
Copy link

Ryeru commented Jun 10, 2018

@NdaJunior It is extremely slow in 0.11.1, I have the same problem

@wzup
Copy link

wzup commented Jun 23, 2018

SLOOOOOWWW

@themakerman
Copy link

SLOWWWWWW........i thought its my code but its the module....

@harshitjee
Copy link

here tooo......very slow

@harshitjee
Copy link

guys i hv improved the slowness issue please check https://github.com/harshitjee/react-native-material-dropdown.git use npm install https://github.com/harshitjee/react-native-material-dropdown.git and give me yr feedback

@sachinar94
Copy link

set there animationDuration to get fast response. slow because of animation at there start.

animationDuration={300}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests