React中onInput事件触发后render与console.log显示值不一致问题
为什么输入内容时页面渲染值和控制台打印值不一致?
在输入元素中输入内容时,会触发onInputChange()函数,该函数更新inputValue状态,随后调用getValue()函数获取inputValue状态并打印到控制台,但页面渲染的值与控制台打印的值不一致,这是什么原因?
可复现代码
import React from 'react'; import './style.css'; export default class App extends React.Component { constructor() { super(); this.state = { inputValue: '', }; } getValue = () => { const { inputValue } = this.state; console.log(inputValue); }; onInputChange = (event) => { const inputValue = event.currentTarget.value; this.setState({ inputValue }); this.getValue(); }; render() { const { inputValue } = this.state; return ( <div> <input placeholder="texto" onInput={this.onInputChange} /> <p>{inputValue}</p> </div> ); } }
原因分析
问题出在React的setState是异步操作。当你调用this.setState更新状态时,React不会立刻修改this.state,而是把这次更新放进队列里,等合适的时机再批量处理更新。所以在setState之后马上调用getValue读取状态,拿到的还是更新前的旧值;但页面渲染会等到状态真正更新完成后才触发,所以页面显示的是最新值,这就导致了控制台打印和页面显示不一致的情况。
举个例子:第一次输入字符'a',onInputChange里拿到的输入值是'a',调用setState后立刻执行getValue,此时this.state.inputValue还是空字符串,控制台打印空;等React处理完状态更新,组件重新渲染,页面才显示'a',两者自然对不上。
解决方法
要想在状态更新后再执行getValue,有两种靠谱的方式:
- 给
setState加个回调函数:这个回调会在状态更新完成、组件重新渲染后触发,此时读取的就是最新状态了。修改后的代码如下:
onInputChange = (event) => { const inputValue = event.currentTarget.value; this.setState({ inputValue }, () => { this.getValue(); // 这里拿到的是更新后的inputValue }); };
- 用
componentDidUpdate生命周期:这个钩子会在组件更新完成后自动执行,我们可以在这里判断状态是否变化,再执行getValue:
componentDidUpdate(prevProps, prevState) { // 只有当inputValue确实变化时才执行 if (prevState.inputValue !== this.state.inputValue) { this.getValue(); } } onInputChange = (event) => { const inputValue = event.currentTarget.value; this.setState({ inputValue }); };
内容的提问来源于stack exchange,提问作者sonEtLumiere
相关产品推荐
相关产品推荐

