反应状态值在本机事件的回调中为空

Posted

技术标签:

【中文标题】反应状态值在本机事件的回调中为空【英文标题】:React state values are empty inside callback from native event 【发布时间】:2020-11-03 12:05:27 【问题描述】:

我有下一个组件:

const [username, setUsername] = useState('');
const [password, setPassword] = useState('');

const handleUserKeyPress = useCallback((event) => 
    if (event.keyCode === 13) 
      doLogin( username, password , loginDispatch, callback);
    
  , []);

  useEffect(() => 
    window.addEventListener('keypress', handleUserKeyPress);
  , [handleUserKeyPress]);

      <ProjectFormField
        label=t('email')
        formInputProps=
          value: username,
          onChange: (event) => setUsername(event.target.value),
        
        inputType="email"
      />

      <ProjectFormField
        label=t('password')
        formInputProps=
          value: password,
          onChange: (event) => setPassword(event.target.value),
        
        type="passwordField"

      />

     <Button
        label='loginEnter'
        id="login-button"
        disabled= !username || !password
        onClick=() => 
          doLogin( username, password );
        
        
      />

     

***ProjectFormField 是我们的 Material ui 文本字段组件的自定义应用包装器

当我点击按钮时,用户名和密码的值存在于状态中。当我按下回车按钮时,回调函数正在工作,但状态中的值为空。 我还尝试了 userRef 的解决方案,其中 ref 是登录组件的包装容器,但结果是一样的。 我做错了什么?

【问题讨论】:

所以,如果我理解正确的话,你填写你的表格,按回车,当回调被调用时,你的状态是空的,尽管表格已经被填写。对吗? 状态参数(usernamepassword)不会在handleUserKeyPress 中更新,因为它是一个使用useCallback 挂钩的函数。您可以将usernamepassword 添加到useCallback 依赖数组中,这将在每次它们中的任何一个更改时更新回调。但出于性能原因,我不建议这样做。 @AdrianPascu 确实是的 @LuudJacobs 这个正在工作,但是我有 3 个回调调用:1)仍然是空状态,2)用户名已满,密码为空,3)状态已满......这种简单形式的正确行为?这个可以避免吗? 我认为@LuudJacobs 是对的。你也不能使用useCallback。由于它是一个登录表单,记忆化不应该对性能有太大的提升。 【参考方案1】:

您可能想在此处使用useRef 钩子。 这是您可以参考的代码框链接:https://codesandbox.io/s/exciting-framework-mprqg?file=/src/index.js

【讨论】:

【参考方案2】:

我今天和上周有一次同样的问题,我推迟了。看到这个问题和答案。然后找到了这个github reply。

在那里我看到了一个关于如何使用useRef 的示例。我发现它使事情变得复杂。但是,最后他概述了将函数传递给setState 函数以更新值。效果很好!

在我的情况下是这样的:

const [posts, setPosts] = useState([]);

useEffect(function onLoad() 
  
  const unregisterEventListener = listenToNewPostEvent();

  return unregisterEventListener;

, []);

function listenToNewPostEvent() 
  
  function handleNewPost(post) 
    // "posts" is empty in this line. 
    // Calling setPosts([post, ...posts]) always left "posts" with one entry.
    // So, I changed as follows as mentioned in the previously given link.
    setPosts(function updatePosts(posts) 
      // Here "posts", which is coming as parameter to this function is the latest one.
      return [post, ...posts];
    );
    // Now the posts array has the latest data & the same gets reflected in the screen as well.
  

  return eventSystem.on(NEW_POST, handleNewPost);



【讨论】:

以上是关于反应状态值在本机事件的回调中为空的主要内容,如果未能解决你的问题,请参考以下文章

反应原生原生模块 RCTBubblingEventBlock 为空

HttpContext.Current 在异步回调中为空

从本机事件发射器回调后,React 本机 UI 未呈现。甚至回调有状态改变

Bootbox Ajax 帖子在回调函数中为空

React-native this.props 在回调函数中为空

反应本机打字稿屏幕测试返回测试套件无法运行 AsyncStorage 为空