0

I have declared a variable like

const [listRealm, setListRealm] = useState([
    {
      value: null,
      label: 'select one',
    },
  ]);

  const findList= async () => {
    await axios.get(`${apiUrl}`).then(resp => {
      resp.data.map(res => {
        setListRealm(listRealm => [...listRealm, { value: res.id, label: res.name}]); // error here
      });
    });
  };


  useEffect(() => {
    findList();
  }, []);

Now my problem is that I receive error:

'listRealm' is already declared in the upper scope @typescript-eslint/no-shadow

I don't understand how I can change name of variable, considering that i'm setting this variable.

How can I do? thank you

2
  • That's not an error anyway, it's just your linter warning about potentially confusing code. Commented Nov 5, 2021 at 10:32
  • 2
    You should be able to simplify this so that you're not calling setListRealm multiple times: setListItems(lstR => [...lstR, ...resp.data.map(res => ({ value: res.id, label: res.name}))]), as a side note .map() for iteration only is not what map should be used for, instead .forEach() can be used Commented Nov 5, 2021 at 10:34

2 Answers 2

4

The name you use in the setListRealm callback can be anything you want, so you can just make it previousListRealm or just previous or something:

setListRealm(previousListRealm => [...previousListRealm, { value: res.id, label: res.name}]);

It doesn't have to match the name of the constant you've put the value from useState in.


A few other suggestions:

  1. As Nick pointed out, you'd be better off doing your map first, and then adding all the elements to state at the same time. (And separately, please see my post Misusing map — map isn't the right tool if you're not using the array it returns.)

  2. Your findList is an async function. In general, it's best to avoid mising async/await with explicit promise methods like then. Just use await without using then.

  3. The code calling findList needs to handle the fact it may reject its promise.

  4. There's no need to re-create the findList function on every render if you only use it on the first render.

  5. There's no point to the template literal in axios.get(`${apiUrl}`), just use axios.get(apiUrl).

So for example:

useEffect(() => {
    const findList = async () => {
        const { data } = await axios.get(apiUrl);
        const additions = data.map(({ id, name }) => ({ value: id, label: name }));
        setListRealm((previous) => [...previous, ...additions]);
    };
    findList()
    .catch((error) => {
        // ...handle.report error...
    });
}, []);

Or don't use an extra function at all:

useEffect(() => {
    axios.get(apiUrl)
    .then(({data}) => {
        const additions = data.map(({ id, name }) => ({ value: id, label: name }));
        setListRealm((previous) => [...previous, ...additions]);
    })
    .catch((error) => {
        // ...handle.report error...
    });
}, []);
Sign up to request clarification or add additional context in comments.

Comments

-1

setListRealm(listRealm <-- You can name it here.

Comments

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.