首页 > 解决方案 > 运行 onChangeText 不能正确更新 TextInput 值

问题描述

我在 react-native 中创建自己的搜索栏,所以我想允许用户清除文本输入。为了实现这一点,我useState用来跟踪文本输入何时value为空。我正在执行onStateChange('')清理文本输入value,问题是如果我访问value这个显示值之前onStateChange('')不是空字符串''

例如,如果我react在输入上键入,然后执行,onStateChange('')我希望输入value属性为空,但它不是,value还包含react,如果我按其他键,则值是''而不是当前值。即它不保存输入的最后一个值,而是保存前一个值。

搜索栏使用

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

function SearchBar(props) {
  const {
    onChangeText,
    value = '',
    ...textInputProps
  } = props;
  // Access to native input
  const textInputRef = React.createRef();
  // Track if text input is empty according `value` prop
  const [isEmpty, setIsEmpty] = useState(value ? value === '' : true);

  const clear = () => {
    // Clear the input value with native text input ref
    textInputRef.current?.clear();
    // Update the text input `value` property to `''` i.e. set to empty, 
    if (onChangeText) onChangeText('');
    // this is where the problem lies, because If I check the input text `value` property, this show the previus one, not the current one.
    console.log(value);
  };

  const handleOnChangeText = (text) => {
    if (onChangeText) onChangeText(text);
    // track if text input `value` property is empty
    setIsEmpty(text === '');
  };

  // Render close icon and listen `onPress` event to clear the text input
  const renderCloseIcon = (iconProps) => (
    <TouchableWithoutFeedback onPress={clear}>
      <View>
        <Icon {...iconProps} name="close" pack="material" />
      </View>
    </TouchableWithoutFeedback>
  );

  return (
    <TouchableWithoutFeedback onPress={focus}>
      <View>
        <TextInput
          {...textInputProps}
          onFocus={handleOnFocus}
          onBlur={handleOnBlur}
          onChangeText={handleOnChangeText}
          ref={textInputRef}
        />
        // helper function to render a component with props pased to it
        <FalsyFC
          style={{ paddingHorizontal: 8 }}
          // If text input `value` is `isEmpty` show the `x` icon   
          component={!isEmpty ? renderCloseIcon : undefined}
        />
      </View>
    </TouchableWithoutFeedback>
  );
}

搜索栏使用

function SomeComponent() {
  const [search, setSearch] = useState('');

  const updateSearch = (query: string) => {
    setSearch(query);
  };

  return (
    <SearchBar
      onChangeText={updateSearch}
      value={search}
    />
  )
}

标签: react-native

解决方案


每个状态变化都是异步的,即使是 Hooks。使用 useState() 即使未调用 onStateChange() 也无法定义回调函数。在您的情况下,您应该使用函数 useEffect()。

function SomeComponent() {
  const [search, setSearch] = useState('');
  useEffect(() => {
  //Write your callback code here
  //copy-paste what you wrote on function onStateChange()
  }, [search]);
  const updateSearch = (query: string) => {
    setSearch(query);
  };

  return (
    <SearchBar
      onChangeText={updateSearch}
      value={search}
    />
  )
}

这是一个可以帮助您的链接:

https://dmitripavlutin.com/react-useeffect-explanation/#:~:text=callback%20is%20the%20callback%20function,dependencies%20have%20changed%20between%20renderings


推荐阅读