【问题标题】: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。由于它是一个登录表单,记忆化不应该对性能有太大的提升。

标签: javascript reactjs material-ui react-hooks


【解决方案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);
    
    }
    
    

    【讨论】:

      猜你喜欢
      • 2020-09-25
      • 1970-01-01
      • 2021-07-20
      • 2019-08-29
      • 1970-01-01
      • 2019-03-26
      • 2021-03-30
      • 2020-05-08
      • 2021-05-19
      相关资源
      最近更新 更多