简体   繁体   English

当前一个状态在组件方法的关闭中时,如何处理 React.js hooks 中的 case?

[英]How to handle case in React.js hooks when the previous state is in the closure of component's method?

I have a component which waits for an API call, sets an empty array as initial state and then on props change it sets the new array.我有一个等待 API 调用的组件,将一个空数组设置为初始状态,然后在道具更改时设置新数组。

const [options, setOptions] = useState([]);

useEffect(() => {
 setOptions(optionsFromProps);
}, [optionsFromProps]);

The problem is, that I have a function inside of the component which has closure over the first empty array and when I call it, it's being called with empty array event though now options is [{}, {}, {}];问题是,我在组件内部有一个函数,它在第一个空数组上有闭包,当我调用它时,它被空数组事件调用,尽管现在选项是 [{}, {}, {}];

// inside of the same component
const foo = () => console.log(options);
// it logs []
// if the initial state would be [1,2,3] then it logs [1,2,3]

After an additional discussion over the problem with my colleague, he pointed out that I haven't understood the problem.在与我的同事进一步讨论这个问题后,他指出我没有理解这个问题。 Basically, the initial question is incorrect and the bug was because in the child component I attached an event listener which had closure over the initial state.基本上,最初的问题是不正确的,错误是因为在子组件中,我附加了一个事件侦听器,该侦听器在初始状态上有闭包。

CodeSundbox example CodeSundbox 示例

So after this, the fix was obvious: on every rerender, the function should be updated, not only on the initial render.所以在这之后,修复是显而易见的:在每次重新渲染时,应该更新函数,而不仅仅是在初始渲染上。

import React, { useState, useEffect } from "react";

const Component = () => {
  const [options, setOptions] = useState([]);

  useEffect(() => {
    const onMouseDown = () => {
      foo();
    };
    document.addEventListener("mousedown", onMouseDown);
    return () => document.removeEventListener("mousedown", onMouseDown);
  }); // fixed
  // }, []); with a bug

  const foo = () => {
    setOptions(options);
  };

  const handleClick = () => {
    setOptions([1, 2, 3]);
  };

  return (
    <div>
      <button onClick={handleClick}>Click me!</button>
      <ul>
        {options.map(option => (
          <li>{option}</li>
        ))}
      </ul>
    </div>
  );
};

export default Component;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM