# 代替 e.target.value

  • 用 ref+箭头函数进行绑定



 
 
 


<input
  value={this.state.inputValue}
  onChange={this.inputChange.bind(this)}
  ref={(input) => {
    this.input = input;
  }}
/>
1
2
3
4
5
6
7
  • 改变 inputChange 方法


 




inputChange(e) {
  this.setState({
    inputValue: e.target.value,
    inputValue: this.input.value,
  });
}
1
2
3
4
5
6
  • PS:不建议用 ref 这样操作的,因为 React 的是数据驱动的,所以用 ref 会出现各种问题

# ref 使用的坑

  • 获取食物数量需要绑定 ul









 






<Fragment>
  <input
    value={this.state.inputValue}
    onChange={this.inputChange.bind(this)}
    ref={(input) => {
      this.input = input;
    }}
  />
  <button onClick={this.addFood.bind(this)}>增加食物</button>
  <ul ref={(ul) => (this.ul = ul)}>
    {this.state.food.map((item, index) => {
      return <FoodItem key={index + item} content={item} index={index} deleteFood={this.deleteFood.bind(this)} />;
    })}
  </ul>
</Fragment>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  • 每次添加一个食物都打印所有食物的总数




 


addFood() {
  this.setState({
    food: [...this.state.food, this.state.inputValue],
  });
  console.log(this.ul.querySelectorAll("li").length);
}
1
2
3
4
5
6
  • 这时候显示的食物总数会少一个,比如 3 个食物 console.log 只有 2 个
  • 这个坑是因为 React 中更多 setState 是一个异步函数所造成的
  • 也就是这个 setState,代码执行是有一个时间的
  • 简单的说,就是因为是异步,还没等虚拟 Dom 渲染,console.log 就已经执行了
  • setState 方法提供了一个回调函数,也就是它的第二个函数





 
 
 



addFood() {
  this.setState(
    {
      food: [...this.state.food, this.state.inputValue],
    },
    () => {
      console.log(this.ul.querySelectorAll("li").length);
    }
  );
}
1
2
3
4
5
6
7
8
9
10

# 完整代码
















 








 
 
 

















 
 
 


 











import React, { Component, Fragment } from "react";
import FoodItem from "./testComp";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: "",
      food: ["苹果", "西瓜"],
    };
  }

  inputChange(e) {
    this.setState({
      // inputValue: e.target.value,
      inputValue: this.input.value,
    });
  }

  addFood() {
    this.setState(
      {
        food: [...this.state.food, this.state.inputValue],
      },
      () => {
        console.log(this.ul.querySelectorAll("li").length);
      }
    );
  }

  deleteFood(index) {
    let food = this.state.food;
    food.splice(index, 1);
    this.setState({
      food: food,
    });
  }

  render() {
    return (
      <Fragment>
        <input
          value={this.state.inputValue}
          onChange={this.inputChange.bind(this)}
          ref={(input) => {
            this.input = input;
          }}
        />
        <button onClick={this.addFood.bind(this)}>增加食物</button>
        <ul ref={(ul) => (this.ul = ul)}>
          {this.state.food.map((item, index) => {
            return <FoodItem key={index + item} content={item} index={index} deleteFood={this.deleteFood.bind(this)} />;
          })}
        </ul>
      </Fragment>
    );
  }
}

export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
上次更新时间: 11/18/2021, 11:42:27 AM