过滤函数的可变版本来过滤React的结果?

时间:2017-11-08 06:33:58

标签: reactjs

我有一个名为renderExercises的函数,我在render函数中调用它。 renderExercises返回一个ExercisesChoose组件数组。

renderExercises() {
    const {selectedType} = this.state;
    const allExercises = this.props.exercises;

    let exercisesToRender = [];

    if (selectedType !== 'all') {
      exercisesToRender = allExercises[selectedType];
    } else {
      exercisesToRender = Object.values(allExercises)
        .reduce((array, subarray) => array.concat(subarray), [])
        .sort();
    }

    return exercisesToRender.map((exercise) => {
      return (
        <ExercisesChoose
          key={exercise}
          name={exercise}
        />
      )
    })
  }

到目前为止这是有效的。但是,如果用户输入了此文本,我还想根据搜索文本进行过滤。

由于无法在现有阵列exerciseToRender上调用过滤器,因此无法正常工作。

    if (typeof this.searchText !== 'undefined') {
      const searchText = this.searchText.value;
      // This is not working 
      exercisesToRender.filter(item => {
        return item.includes(searchText);
      });
    }

这是什么解决方案?是否有允许变异的排序方法?如果是这样,这是否可取用?

这是我目前的解决方案,但有点难看:

renderExercises() {
    const {selectedType} = this.state;
    const allExercises = this.props.exercises;

    let exercisesToRender = [];

    if (selectedType !== 'all') {
      exercisesToRender = allExercises[selectedType];
    } else {
      // Combine all the different exercise groups into a single array
      exercisesToRender = Object.values(allExercises)
        .reduce((array, subarray) => array.concat(subarray), [])
        .sort();
    }

    let render = [];

    if (typeof this.searchText !== 'undefined') {
      const searchText = this.searchText.value;
      render = exercisesToRender.filter(item => {
        return item.includes(searchText);
      });
    } else {
      render = exercisesToRender;
    }

    return render.map((exercise) => {
      return (
        <ExercisesChoose
          key={exercise}
          name={exercise}
        />
      )
    })
  }

这是我的练习对象的样子:

this.props.exercises = [
  legs:["Squat", "Power squats", "Burpees"]
  pull:["Pull up", "Chin up", "Dumbbell curl", "Horizontal row"]
  push:["Push up", "Bench press", "Dumbbell bench press", "Mountain climbers"]
  cardio: ["Running high knees", "Plank", "Crunches", "Skipping"]
]

2 个答案:

答案 0 :(得分:1)

我对此案的策略是:

  1. reducetype
  2. 过滤练习
  3. filter他们searchText
  4. sort
  5. map呈现
  6. 最终结果:

    renderExercises() {
      const { selectedType } = this.state
      const { exercises: allExercises }  = this.props
    
      return Object
        .keys(allExercises)
        .reduce((result, key) => {
          if (selectedType === 'all' || key === selectedType) {
            return [
              ...result,
              ...allExercises[key],
            ]
          }
    
          return result
        }, [])
        .filter(exercise => searchText ? exercise.includes(searchText) : true)
        .sort()
        .map(exercise =>
          <ExercisesChoose
            key={exercise}
            name={exercise}
          />
        )
    }
    

    &#13;
    &#13;
    const exercises = {
      legs:["Squat", "Power squats", "Burpees"],
      pull:["Pull up", "Chin up", "Dumbbell curl", "Horizontal row"],
      push:["Push up", "Bench press", "Dumbbell bench press", "Mountain climbers"],
      cardio: ["Running high knees", "Plank", "Crunches", "Skipping"],
    }
    
    const filterExercises = (type, searchText) => {
      return Object
        .keys(exercises)
        .reduce((result, key) => {
          if (type === 'all' || key === type) {
            return [
              ...result,
              ...exercises[key],
            ]
          }
    
          return result
        }, [])
        .filter(exercise => searchText ? exercise.includes(searchText) : true)
        .sort()
        .join(', ')
    }
      
    console.log('All exercises:', filterExercises('all', ''))
    console.log('All (up):', filterExercises('all', 'up'))
    console.log('Push:', filterExercises('push', ''))
    console.log('Push (press):', filterExercises('push', 'press'))
    &#13;
    &#13;
    &#13;

答案 1 :(得分:0)

我对mersocarlin的答案略有扩展,因为我从searchText得到了一些错误的结果,但基本上他的逻辑确实有效。

renderExercises() {
    const {selectedType} = this.state;
    const allExercises = this.props.exercises;

    let searchText = false;
    if (this.searchText && this.searchText.value.length > 0) {
      searchText = this.searchText.value.toLowerCase();
    }

    return Object
      .keys(allExercises)
      .reduce((result, key) => {
        if (selectedType === 'all' || key === selectedType) {
          return [
            ...result,
            ...allExercises[key]
          ]
        }
        return result
      }, [])
      .filter(exercise => searchText ? exercise.toLowerCase().includes(searchText) : true)
      .map((exercise) => {
        let active = false;
        if (this.props.chosenExercise === exercise) {
          active = true;
        }
        return (
          <ExercisesChoose
            key={exercise}
            name={exercise}
            active={active}
            setNumber={this.props.number}
            updateValue={this.props.updateValue}
          />
        )
      })
  }