首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反应本机useState同步

反应本机useState同步
EN

Stack Overflow用户
提问于 2020-09-15 18:48:35
回答 1查看 194关注 0票数 2

我有一个具有状态"text“的组件TextInput,它表示它的值。此外,我还有另一个组件UsernameTextInput,它包装TextInput并包含状态"isUsernameAvailable",它指示是否允许在数据库中写入文本输入的当前值。

由于useState是异步的,有时当用户输入非常快时,对应于类型化用户名的isUsernameAvailable是错误的。例如,用户名"tarantino“不可用,但有时,在我当前的代码中,它是可用的,因为useState是异步的,我没有正确地处理它.

有什么办法让这段时间同步吗?

以下是我的当前代码:

代码语言:javascript
复制
function UsernameInput(props) {    
  const [isUsernameAvailable, setIsUsernameAvailable] = useState(undefined);

  const usernameInputRef = useRef(null);

  const previousValues = useRef(null);

  const checkUsername = async () => {
    const { firebase } = props;

    // Get the username
    const username = usernameInputRef.current.getText();

    
    // Check if the username is valid and available on the database
    const isUsernameAvailable = validateUsername(username) &&
                          (await firebase.isUsernameAvailable(username));

    setIsUsernameAvailable(isUsernameAvailable);
  };

  useEffect(() => {
    // Get the username from the text input
    const username = usernameInputRef.current.getText();

    if (
      previousValues.current?.username !== username &&
      previousValues.current?.isUsernameAvailable !== isUsernameAvailable
    ) {          
        console.log(`${username} - ${isUsernameAvailable}`)
        
        // Update previousValues reference
        previousValues.current = { username, isUsernameAvailable };
    }
  });

  return (
    <TextInput
      ref={usernameInputRef}
      onChange={checkUsername}
    />
  );
}

TextInput伪码

代码语言:javascript
复制
 TextInput(props, ref) {
    const getTextInput = () => text;

    const [text, setText] = useState(null)
    
    useEffect(() => {
        const { onChange } = props;
        if(text) onChange();   
    }, [text]);  
 
    return <NativeTextInput value={text} onChange={(e) => setText(e.nativeEvent.text)}/>
    ...
 }

快速写入返回用户名“tarantino”的不同值: tarantino - true \tarantino- false

我认为这里的问题是UsernameInput "isUsernameAvailable“的状态比TextInput状态"text”更新得更快,也许不是错误,但我认为是错误。

有什么办法解决我的问题吗?谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-15 19:56:17

您是否考虑过添加一个脱去来处理类型,并且只在用户停止输入之后才调用firebase.isUsernameAvailable端点?

代码语言:javascript
复制
const checkUsername = async () => {
    const { firebase } = props;

    // Get the username
    const username = usernameInputRef.current.getText();

    // Check if the username is valid and available on the database
    const isUsernameAvailable = validateUsername(username) && (await firebase.isUsernameAvailable(username));

    setIsUsernameAvailable(isUsernameAvailable);
};

// The debounced function that you call instead of checkUsername
const debouncedCheck = debounce(checkUsername, 500);

我看不出await每一次击键都是一个很好的实践,更不用说遇到像您正在经历的那种错误的可能性了。

编辑:

不要在onChange中调用useEffect道具,而是尝试使用这个方法。

代码语言:javascript
复制
TextInput(props, ref) {
    const getTextInput = () => text;

    const [text, setText] = useState(null)

    const handleChange = async (value) => {
      const { onChange } = props;
      setText(value);
      await onChange(value);
    }
 
    return <NativeTextInput value={text} onChangeText={handleChange}/>
    ...
 }

这样,您就可以不用在您的usernameInputRef.current.getText();方法中执行这个checkUsername了,您可以只使用作为参数传入的username值。

代码语言:javascript
复制
const checkUsername = async (username) => {
    const { firebase } = props;

    // Check if the username is valid and available on the database
    const isUsernameAvailable = validateUsername(username) && (await firebase.isUsernameAvailable(username));

    setIsUsernameAvailable(isUsernameAvailable);
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63908120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档