开发者问题收集

数组过滤器不适用于状态

2018-08-17
5587

我有一个状态数组,状态的值显示在视图中,我还有一个文本视图,我想让文本输入的值改变状态的值,这样状态视图中的值就会改变,但不会改变状态视图中的值, 即如果我输入 a ,视图不会改变,如果我输入 ab ,它会返回一个错误,提示 undefined 不是对象(正在评估 item.toLowerCase) 请问我哪里可能错了

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      schools: [
        "Abubakar Tafawa Balewa University, Bauchi",
        "Ahmadu Bello University, Zaria",
        "Bayero University, Kano",
      ],
    };
    this.handleChange = this.handleChange.bind(this);
    this.schoolChange = this.schoolChange.bind(this);
  }

  schoolChange(text) {
    for (let i = 0; i < this.state.schools.length; i++) {
      console.log(this.state.schools[i]);
    }
    let c = this.state.schools.map(item => item.toLowerCase(item));
    let b = c.filter(item => item.indexOf(text) > -1);
    let d = b.map(item => item.toUpperCase(item));
    console.log(d);
    var len = d.length;
    for (let i = 0; i < len; i++) {
      let row = d[i];
      this.setState(
        prevState => ({
          schools: [...prevState.schools, row],
        }),
        console.log(this.state.schools[i]),
      );
    }
  }

  handleChange(text) {
    this.setState({ text }, () => {
      this.schoolChange(this.state.text);
    });
  }

  render() {
    const schools = this.state.schools.map((school, index) => (
      <Text style={styles.text}>{school}</Text>
    ));

    return (
      <View>
        <TextInput
          placeholder="Search"
          value={this.state.text}
          onChangeText={text => this.handleChange(text)}
        />
        <ScrollView overScrollMode={"never"} keyboardShouldPersistTaps="always">
          {schools}
        </ScrollView>
      </View>
    );
  }
}
2个回答

这是因为您正在覆盖学校数组,现在没有数据可供过滤。您的数据源是 this.state.schools ,在过滤器上,您正在用新数据(可能是空数组)替换学校数组,因此现在您没有办法将数据返回到过滤器。因此,不要将源数据保存在状态中,而是将其保存在一些全局变量中或 this.schools 中,这样更新状态就不会改变源

保留数据的副本。您不需要在循环中设置状态。只需计算数据然后设置状态即可。

constructor(props) {
    super(props);
        this.schools = [
                   "Abubakar Tafawa Balewa University, Bauchi",
                   "Ahmadu Bello University, Zaria",
                   "Bayero University, Kano"
                ];
        this.state = {
                schools: this.schools
        }

    this.handleChange = this.handleChange.bind(this);
}
  
 handleChange(text){
     const schools = this.schools.filter(name => name.toLowerCase().indexOf(text.toLowerCase()) > -1);
     this.setState({ schools });
 }
Zohaib Ijaz
2018-08-17

您还可以简化 schoolChange 函数:

schoolChange(text){
     const schools = this.schools.filter(school => school.toUpperCase().includes(text.toUpperCase()));
     this.setState({
       schools,
     });
 }
Peter Nagy
2018-08-17