admin管理员组

文章数量:1290938

I have a dropdown menu which has a controlled state. If the user changed the dropdown value and if the input is not empty, fire a function passed from other ponent.

export default ({ triggerChange, inputVal }) => {
  const [dropdown, setDropdown] = useState(1);

  useEffect(() => {
    if (inputVal) {
      triggerChange(dropdown);
    }
  }, [dropdown]); // this line throw a warning

  const handleChange = e => {
    setDropdown(e.target.value);
  };

  return (
    <div>
      <select onChange={handleChange}>
        <option value="1">1</option>
        <option value="2">2</option>
      </select>
    </div>
  );
};

codesandbox

Error

React Hook useEffect has missing dependencies: 'inputVal' and 'triggerChange'. Either include them or remove the dependency array. If 'triggerChange' changes too often, find the parent ponent that defines it and wrap that definition in useCallback. (react-hooks/exhaustive-deps)

I have a dropdown menu which has a controlled state. If the user changed the dropdown value and if the input is not empty, fire a function passed from other ponent.

export default ({ triggerChange, inputVal }) => {
  const [dropdown, setDropdown] = useState(1);

  useEffect(() => {
    if (inputVal) {
      triggerChange(dropdown);
    }
  }, [dropdown]); // this line throw a warning

  const handleChange = e => {
    setDropdown(e.target.value);
  };

  return (
    <div>
      <select onChange={handleChange}>
        <option value="1">1</option>
        <option value="2">2</option>
      </select>
    </div>
  );
};

codesandbox

Error

React Hook useEffect has missing dependencies: 'inputVal' and 'triggerChange'. Either include them or remove the dependency array. If 'triggerChange' changes too often, find the parent ponent that defines it and wrap that definition in useCallback. (react-hooks/exhaustive-deps)

Share Improve this question edited Aug 7, 2019 at 9:01 Edgar 6,85811 gold badges38 silver badges74 bronze badges asked Aug 7, 2019 at 3:29 HanzHanz 5191 gold badge8 silver badges19 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

Add those to the dependency:

useEffect(() => {
  if (inputVal) {
    triggerChange(dropdown);
  }
}, [dropdown, inputVal]);

This will only re-run the effect if either dropdown or inputVal values change.

For triggerChange:

if dropdown changes frequently, use useCallback hook.

// Parent.js
const memoizedTriggerChange = useCallback(
  () => {
    triggerChange(dropdown);
  },
  [dropdown],
);

useEffect(() => {
  if (inputVal) {
    memoizedTriggerChange();
  }
}, [inputVal]);

EDIT

based on the OPs codesandbox

// index.js
const triggerChange = useCallback(() => {
  console.log("call api");
}, []); // not depending on inputVal to prevent firing if inputVal changes

// AnotherComp.js
useEffect(() => {
  triggerChange(dropdown);
}, [dropdown, triggerChange]);
useEffect(() => {
    if (inputVal) {
      triggerChange(dropdown);
    }
  }, [dropdown]); // this line throw a warning

In this piece of code, if you notice, inputVal, triggerChange and dropdown are variables and they are dependencies to useEffect hook because useEffect gets triggered whenever any change is made to any of the aforementioned dependencies.

To satisfy the basic working principle of useEffect hook, we should pass those depdencies in useEffect's array parameter.

  useEffect(() => {
    if (inputVal) {
      triggerChange(dropdown);
    }
  }, [dropdown, triggerChange, inputVal]);

本文标签: javascriptuseEffect throw warning for dependecyStack Overflow