skip to Main Content

I am trying to access the students variable by putting its value in a state then accessing that state in my handler function but it always returns an empty array.

const students = useSelector((state) => state.students);
useEffect(() => {
  setdata(students);
  console.log(data);
}, [])
const handleScanWebCam = (result, error) => {
  if (result) {
    console.log(data)

    const list = data.filter(function (student) {
      return student.id === result.text;
    })
            
    setScanResultWebCam({
      id: list.id,
      grade: list.grade,
      name: list.name,
      section: list.section
    });

  }
}

this is my full code

function QrScanner() {
  const dispatch = useDispatch(getStudents())

  useEffect(() => {
    dispatch(getStudents());
  }, [dispatch])

  const students = useSelector((state) => state.students);

  const [scanResultWebCam, setScanResultWebCam ] = useState({
    id: '',
    grade: '',
    name: '',
    section:''
  });

  const [openVerifier, setOpenVerifier] = useState(false);
  const [data, setdata] = useState([]);

  useEffect(() => {
    setdata(students);
    console.log(data);
  }, [])

  const handleScanWebCam = (result, error) => {
    if (result) {
      const list = data.filter(function (student) {
        return student.id === result.text;
      })
            
      setScanResultWebCam({
        id: list.id,
        grade: list.grade,
        name: list.name,
        section: list.section
      });

      setOpenVerifier(true);
    }
  }

  return (
    <>
      <NavBar />
      <Container
        sx={{
          display: 'flex',
          marginTop: '4rem',
          flexWrap: 'wrap',
          gap: '12px',
          width: '90%'
        }}
      >
        <Box
          sx={{
            width: '50%',
            border: 'solid',
            display: 'flex',
            flex: '1'
          }}
        >
          <QrReader
            scanDelay={500}
            containerStyle={{ width: '25rem', margin: 'auto'}}
            onResult={handleScanWebCam}
            // onError={handleErrorWebcam}
          />
        </Box>
        <PopupVerifier 
          details={scanResultWebCam}
          verifier={openVerifier}
          handleClose={() => handleClose()}
        />
      </Container>
    </>
  )
}

2

Answers


  1. If you need to cache a "duplicate" of the selected students state then I’d recommend caching students in a React ref that can have its current value read at any time during the component lifecycle, especially in stale closures.

    Example:

    function QrScanner() {
      const dispatch = useDispatch(getStudents());
    
      useEffect(() => {
        dispatch(getStudents());
      }, [dispatch]);
    
      const students = useSelector((state) => state.students);
      const studentsRef = React.useRef(students);
    
      useEffect(() => {
        studentsRef.current = students;
      }, [students]);
    
      ...
    
      const handleScanWebCam = (result, error) => {
        if (result) {
          const list = studentsRef.current.find(
            (student) => student.id === result.text
          );
    
          if (list) {
            setScanResultWebCam(list);
          }
    
          setOpenVerifier(true);
        }
      };
    
      return (
        ...
      );
    }
    
    Login or Signup to reply.
  2. You have using from react-redux. so you dont need to set student state.

    and dispatch is used for change in store not getting data from it.

    if you want to get an item from array use find instead of filter :

    const list = students.find(student=>student.id===result.text);
    

    i edit your code to :

    function QrScanner() {
      
      const students = useSelector((state) => state.students);
    
      const [scanResultWebCam, setScanResultWebCam ] = useState({
          id: '',
          grade: '',
          name: '',
          section:''
      });
      const [openVerifier, setOpenVerifier] = useState(false);
      const handleScanWebCam = (result, error) => {
          if(result) {
              const list = students.find(student=> student.id === result.text);
              setScanResultWebCam({id: list.id, grade: list.grade, name: list.name, section: list.section});
              setOpenVerifier(true);
          }
    
      }
    
      return(
          ...
      )
    }
    
     
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search