Home > Enterprise >  React UseEffect Updating State but no Rerender
React UseEffect Updating State but no Rerender

Time:07-27

I have an extremely simple issue in which I would like to load input devices and list them. enter image description here

enter image description here

edit: the setinputs([inputDevices]) was an accident, thank you all who reminded me about the asynchronicity of the promise :)

CodePudding user response:

The issue is setInputs will be execute before the then callback, so you need to setInputs inside the then callback, and you can use map to get the list of labels.

    let inputDevices = [];
    navigator.mediaDevices.enumerateDevices().then((devices) => {
      setInputs(devices.map((device) => device.label))
    });

CodePudding user response:

  let inputDevices = [];
    navigator.mediaDevices.enumerateDevices().then((devices) => {
      devices.forEach((device) => inputDevices.push(device.label));
    });
    setInputs([inputDevices]);

You need to call set state inside then. Promises are resolved asynchronously hence when you call setInputs where you have it by that time data isn't there yet.

You can also just utilize map:

setInputs(devices.map((device) => device.label)) // inside .then

CodePudding user response:

Promises are resolved asynchronously so you need to push the setInputs(inputDevices) inside then.

You can change your code too,

navigator.mediaDevices.enumerateDevices().then((devices) => {
   return devices.map(device => device.label);
 })
.then(transformedArray => setInputs(transformedArray))

And one more thing in your code, you are setting the state like this

setInputs([inputDevices]); // like an array inside array

But inside your code, you are accessing it like,

 {inputs.map((device, index) => {
          return (
            <li key={index}>
              id:{index} - Device: {device}{" "}
            </li>
          );
 })}

So change it to,

inputs[0].map()

or update the state like this,

setInputs(inputDevices)
  • Related