使用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()之后不调用渲染?
答案 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()被调用了。很奇怪。