React:调用this.setState()后不调用组件的render()

时间:2018-07-26 05:36:12

标签: reactjs

使用render()更改状态后,不会调用我组件的this.setState()方法。

这是更改组件状态的方法(已调用它,并且我已经对此进行了验证):

  handlePhoneNumberChange = name => (event) => {
    const { contactPhone } = this.state;

    const index = name;
    const phoneEntry = contactPhone[index];
    phoneEntry.phoneNumber = event.target.value;
    this.setState({ contactPhone });
  };

这是组件的初始状态:

  constructor(props) {
    super(props);

    this.state = {
      contactPhone: [{ phoneNumber: '', phoneType: '' }],
    };
  }

这是TextField的呈现方式:

{contactPhone.map((phone, index) => (
    <div key={index}>
                <TextField
                  id={String(Math.random())}
                  label="Phone number"
                  type="tel"
                  value={phone.phoneNumber}
                  onChange={this.handlePhoneNumberChange(index)}
                  placeholder="Contact phone number"
                  margin="normal"
                />
                <br />
    </div>
))}

为什么在setState()之后不调用渲染?

5 个答案:

答案 0 :(得分:1)

您的handlePhoneNumberChange函数直接改变状态。 React docs states切勿直接更改this.state,因为此后调用setState()可能会替换您所做的更改。将this.state视为不可变。

最简单的修复方法是克隆 contactPhone,对其进行更改并将其传递给状态

handlePhoneNumberChange = index => (event) => {
  const contactPhone = [...this.state.contactPhone]; // at this point contactPhone !== this.state.contactPhone
  const phoneEntry = contactPhone[index];
  phoneEntry.phoneNumber = event.target.value;
  this.setState({ contactPhone });
};

应该工作!


const cloneArray = [...someArray]; // spread syntax

相同
const cloneArray = someArray.slice(0);

两者都产生一个数组,该数组包含与someArray相同的值,但不是相同的数组。

答案 1 :(得分:0)

将列表密钥分配给随机的字符串化数字key={String(Math.random())}是一个糟糕的主意,因为该密钥将随每个渲染调用而变化,并且当{{1时,React无法正确调和虚拟DOM。 }}被调用。 React通过使用相同的键来区分列表项来跟踪哪些列表项已更改。

有关React对帐的更多详细信息,请参见下面的链接: https://reactjs.org/docs/reconciliation.html#keys

答案 2 :(得分:0)

我认为您需要重新访问handlePhoneNumberChange函数: 您在此处未进行更改,而是两次设置了相同的值。 Array contactPhone的引用是相同的

handlePhoneNumberChange = name => (event) => {
    // its destructed, but not changed later
    const { contactPhone } = this.state;
    //  no changes
    const index = name;
    const phoneEntry = contactPhone[index];
    phoneEntry.phoneNumber = event.target.value;

    // you set same value, nothing changed
    this.setState({ contactPhone });
  };

答案 3 :(得分:0)

您不在此处修改状态。您正在将其设置为与最初相同的值。 更新代码如下。

handlePhoneNumberChange = name => (event) => {
    const { contactPhone } = this.state;
    const index = name;
    const phoneEntry = contactPhone[index];
    phoneEntry.phoneNumber = event.target.value;
    contactPhone = [...contactPhone,phoneEntry]
    this.setState({ contactPhone });
};

答案 4 :(得分:0)

我不知道为什么会这样,但是可以解决它:

我更改了:

this.setState({ contactPhone: [...contactPhone] });

收件人:

[...contactPhone]

System.out.println(i); // 1 (initial value) System.out.println(++i); // 2 (pre increment returns the value after increment) int a = 1; System.out.println(a++); // 1 (initial value prior to increment, since post increment // returns the value prior to increment) System.out.println(++a); // 3 (pre increment returns the value after increment) 只是创建一个新对象。但是现在render()被调用了。很奇怪。