【问题标题】:onChange in React doesn't capture the last character of textReact 中的 onChange 不会捕获文本的最后一个字符
【发布时间】:2016-01-10 08:47:46
【问题描述】:

这是我的渲染函数:

  render: function() {
    return  <div className="input-group search-box">
              <input
                onChange={this.handleTextChange}
                type="text"
                value={this.state.text}
                className="form-control search-item" />
              <span className="input-group-btn"></span>
        </div>
   }

我把它作为我的事件处理程序:

   handleTextChange: function(event) {
     console.log(event.target.value);
     this.setState({
       text: event.target.value
     });
   }

问题是,当我“保存”一个项目或 console.log 打印输出时,最后一个字符丢失了 - 例如,如果我输入“first”,我会打印出“firs”,并且需要有另一个关键事件来捕获最后一个字符。我试过onKeyUp——它不允许我输入任何东西,我也试过onKeyDownonKeyPress,它什么也不输出。 这里发生了什么,为什么?我怎样才能让最后一个角色出现?

【问题讨论】:

  • 看起来几乎和这个例子一模一样:facebook.github.io/react/docs/forms.html - 还有什么可以修改这个范围的吗?
  • 您的组件还有哪些其他反应功能? getInitialState() 中有什么内容?
  • 您是如何保存或console.loging 的?请记住 setState 是异步的:stackoverflow.com/questions/32674174/…
  • 我遇到了同样的问题。我从 event.target.value 设置状态,然后将新状态分配给数据存储。最后一个角色没有进入商店。相反,我将 event.target.value 分配给状态和商店。最后一个字符现在进入数据存储区。

标签: javascript reactjs


【解决方案1】:

您何时记录状态?请记住,setState 是异步的,因此如果要打印 new 状态,则必须使用回调参数。想象一下这个组件:

let Comp = React.createClass({
  getInitialState() {
    return { text: "abc" };
  },

  render() {
    return (
      <div>
        <input type="text" value={this.state.text}
               onChange={this.handleChange} />
        <button onClick={this.printValue}>Print Value</button>
      </div>
    );
  },

  handleChange(event) {
    console.log("Value from event:", event.target.value);

    this.setState({
      text: event.target.value
    }, () => {
      console.log("New state in ASYNC callback:", this.state.text);
    });

    console.log("New state DIRECTLY after setState:", this.state.text);
  },

  printValue() {
    console.log("Current value:", this.state.text);
  }
});

在输入末尾键入d 将导致以下内容被记录到控制台:

Value from event: abcd
New state DIRECTLY after setState: abc
New state in ASYNC callback: abcd

请注意,中间值缺少最后一个字符。 Here's a working example.

【讨论】:

  • 该死的。这很烦人
  • 我完全忘记了 setState 回调。感谢您发布此信息。这帮助我解决了一个类似但不相关的问题。
【解决方案2】:

由于 setState() 函数是异步的,所以我使用了 await。我使用 async 和 await 实现了这一点,这是我的代码

render: function() {
    return  <div className="input-group search-box">
              <input
                onChange={(e) => {this.handleTextChange(e)}}
                type="text"
                value={this.state.text}
                className="form-control search-item" />
              <span className="input-group-btn"></span>
        </div>
   }

handleTextCahnge 函数:

handleTextChange = async function(event) {

     await this.setState({text: event.target.value});
     console.log(this.state.text);
   }

【讨论】:

  • async await 应该可以工作,但它在函数组件 state hooks 中对我来说不起作用。然后我所做的是,调用函数onBlur 并检查值。希望这会对某人有所帮助。
  • 工作得很好——花了一些时间来解决这个问题。什么被认为是这里的最佳实践?大多数其他答案涉及(1)调度事件以提示更改,或(2)将其包装在句柄函数中。
【解决方案3】:

由于 React v.16.8 反应钩子可能会有所帮助。 我会推荐 useState 和 useEffect。 示例在 React Native 中,但是它应该展示如何使用 useEffect。更多关于useEffect的信息:https://reactjs.org/docs/hooks-effect.html

import React, {useState, useEffect} from 'react';
import { TextInput } from 'react-native';

export interface Props{}
 
const InformationInputs: React.FC<Props> = (props) => {
  const [textInputs, setTextInputs] = useState("");

  const handleValueChange = () => {
    console.log(textInputs);
  }

  useEffect(() => {
    handleValueChange();
  }, [textInputs]);

return (
    <TextInput
    placeholder={'Text'}
    onChangeText={(value: string) => { setTextInputs(value) }}
    />
);
};

【讨论】:

    【解决方案4】:

    setState() 函数是异步的。在不使用回调的情况下,您可以使用另一个辅助变量来立即存储和使用更新的值。喜欢:

    export default class My_class extends Component{
    constructor(props)
    {
    super(props):
    this.state={
    text:"",
    };
    this.text="";
    }
     render: function() {
        return  <div className="input-group search-box">
                  <input
                    onChange={this.handleTextChange}
                    type="text"
                    value={this.state.text}
                    className="form-control search-item" />
                  <span className="input-group-btn"></span>
            </div>
       }
    
    handleTextChange: function(event) {
         console.log(event.target.value);
         this.text = event.target.value;
         this.setState({
          text: event.target.value
         });
       }
    

    您将立即在 this.text 变量中获得更新后的值。但是您应该使用 this.state.text 在您的 UI 中显示文本。

    【讨论】:

      【解决方案5】:
      import React, { useState, useEffect } from 'react';
      
      const MyComponent = () => {
      
          const [userInput, setUserInput] = useState("");
      
          const changeHandler = (e) => {
              setUserInput(e.target.value);
          }
      
          useEffect(()=> {
              //here you will have correct value in userInput 
          },[userInput])
      
          return (
              <div>
                   <input onChange={changeHandler} value={userInput}></input>
              </div>
          )
      }
      

      【讨论】:

      • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation 将通过展示为什么这是解决问题的好方法,并使其对有其他类似问题的未来读者更有用,从而大大提高其长期价值。请edit您的回答添加一些解释,包括您所做的假设。
      【解决方案6】:

      您在设置状态之前打印到控制台。设置状态后写入控制台日志。它将显示全文。 (我有同样的问题)

      handleTextChange: function(event) {
           **console.log(event.target.value)**
      
      
           this.setState({
               text: event.target.value
           });
      }
      

      【讨论】:

        【解决方案7】:

        React v. 16.8 开始,您可以使用 react 挂钩。

        import React, { useState } from 'react';
        
        const MyComponent = () => {
        
            const [userInput, setUserInput] = useState("");
        
            const changeHandler = (e) => {
                setUserInput(e.target.value);
            }
        
            return (
                <div>
                     <input onChange={changeHandler} value={userInput}></input>
                </div>
            )
        }
        

        它对我很有用。

        【讨论】:

        • 它确实捕获了target.value,但它仍然无法捕获OP所需的最后一个字符。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-03
        • 2013-01-18
        • 1970-01-01
        相关资源
        最近更新 更多