Проблема в синхронной работе localstorage - PullRequest
0 голосов
/ 28 мая 2020

Я пытаюсь получить почту пользователя из localstorage, но электронная почта не обновляется мгновенно. Решения, которые я пробовал - 1. Используя электронную почту в массиве зависимостей, это обновляет электронную почту, но люди не перерисовываются в DOM. 2. Использование электронной почты и людей в массиве зависимостей, что вызывает бесконечный вызов useEffect. 3. Я пробовал это без обещаний, непосредственно в последовательном потоке, который также не обновляет электронную почту. Предложите правильный способ решения этой проблемы.

    const [people,setPeople]=useState([])
    const [email,setEmail] = useState('')
    useEffect(()=>{
        new Promise((res,rej)=>{
            setEmail(localStorage.getItem('userid')) //here is issue
            if(email) res();
            else rej(email);
        }).then(
            fire.firestore()
            .collection('Users').where('Email','==',email)
            .get().then((snapshot)=>{
                console.log(snapshot)
                setPeople(snapshot.docs[0].data().Name)
            })
            .catch(e=>{console.log(e)})
        )
        .catch((e)=>{console.log(e)})

    },[email,people])

Ответы [ 2 ]

0 голосов
/ 28 мая 2020

Оборачивание вызова localStorage в Promise усложняет задачу. Вам нужно сделать вызов firestore, когда электронная почта изменится. Ниже приведены два решения, которые я могу предложить.

  1. Первое запускается только тогда, когда компонент монтирует и удаляет электронную почту из состояния.
const [people, setPeople] = useState([]);

useEffect(() => {
  // you might need to wrap this in a try catch as it may fail if a user has disabled access to localStorag
  const email = localStorage.getItem("userid");

  if (email) {
    fire
      .firestore()
      .collection("Users")
      .where("Email", "==", email)
      .get()
      .then((snapshot) => {
        console.log(snapshot);
        setPeople(snapshot.docs[0].data().Name);
      })
      .catch((e) => {
        console.log(e);
      });
  }
}, []);
Если вы хотите, чтобы эффект огненного хранилища запускался при изменении электронного письма. Вы можете разделить эти два эффекта и сделать так, чтобы эффект хранилища зависел от изменений электронной почты, как показано ниже.
const [people, setPeople] = useState([]);
const [email, setEmail] = useState('');

useEffect(() => {
  const localStorageEmail = localStorage.getItem("userid");
  if (email) {
    setEmail(localStorageEmail);
  }
}); // dependence array ignored will run everytime the component rerenders

useEffect(() => {
  if (!email) return;

  fire
    .firestore()
    .collection("Users")
    .where("Email", "==", email)
    .get()
    .then((snapshot) => {
      console.log(snapshot);
      setPeople(snapshot.docs[0].data().Name);
    })
    .catch((e) => {
      console.log(e);
    });
}, [email]);
0 голосов
/ 28 мая 2020

Вы можете разделить функцию получения электронной почты и людей. Я предполагаю, что вы хотите получать людей только тогда, когда у вас есть электронная почта.

  • Получение электронной почты после первоначального рендеринга компонента
  • Затем создайте useEffect для fire.firestore()... зависимостей - это электронная почта

   const [people,setPeople]=useState([])
    const [email,setEmail] = useState('')
    useEffect(()=>{
        setEmail(localStorage.getItem('userid'))
    },[])
    
    useEffect(()=>{
     if(email){
        fire.firestore()
            .collection('Users').where('Email','==',email)
            .get().then((snapshot)=>{
                console.log(snapshot)
                setPeople(snapshot.docs[0].data().Name)
            })
            .catch(e=>{console.log(e)})
      } 
    },[email])
    
...