1

I have a functional component with Hooks:

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

  const getOption = type => options.find(el => el.name === type);

  useEffect(() => {
    fetch('someURL')
      .then(resp => resp.json())
      .then(result => setOptions(result.data), error => console.log(error));
    // trying to check options array now
    console.log(getOption('type')); // returns undefined
  }, []);
}

The purpose of this approach is to fetch a data, then run this data through a computed function, to get a single object based on getOption(type). If i use useEffect(() => fetch(), [options]); then i'll get endless loop with console.log() outputs.

So, setOptions(result.data) is async i guess, just like setState in a class component, but doesn't accept a second parameter to use when async request is done.

I want to modify my options array after a fetch() is done with my getOption() function.

1
  • A solution could be to circumvent the problem and write a system that "takes" synchronous request to "do" something asynchronous, and has query system to check the state of the asynchronous function. Basically a high level interface around promises.... But I hope there's a better solution than that. Commented Jan 26, 2020 at 19:13

1 Answer 1

1

You could use another useEffect to execute a function when options is modified:

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

  const getOption = type => options.find(el => el.name === type);

  useEffect(() => {
    fetch('someURL')
      .then(resp => resp.json())
      .then(result => setOptions(result.data), error => console.log(error));
  }, []);

  useEffect(() => {
    if (!options) {
      return;
    }

    console.log(getOption('type'));
  }, [options])
}
Sign up to request clarification or add additional context in comments.

6 Comments

This works, but i have a question, why do i have 2 console outputs? First one is undefined and a 2nd one is with an actual data, as expected. But why the first one even fires with undefined data? Seems like i understand this, it fires undefined because on the mounted stage, my options array is empty, then when options are filled from API - i get a correct data output in a console. But is there a more elegant way to this?
As mentioned in React Documentation: The function passed to useEffect will run after the render is committed to the screen. meaning that the first time your component renders (fetch has not ended yet), the console.log will be executed, thus the undefined. See: reactjs.org/docs/hooks-reference.html#useeffect
Yeah, i just figured out it now, but is there a better approach for this? Is it perfectly fine to use multiple useEffect() in a single component?
I've edited my answer. You can check if options is defined before executing the function.
A check if (!options) return; doesn't prevent from undefined console output on the component mount stage.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.