Как получить доступ к результату firebase снаружи, затем метод React

#reactjs #firebase

#reactjs #firebase

Вопрос:

я новичок в react и firebase.

ПРОБЛЕМА:

Я пытаюсь получить доступ к переменной, которая возвращает true, когда она успешно получает результат, она работает внутри.метод then, но метод outside then не может получить результат (переменная isStudent). Мне были бы полезны любые предложения, подсказки.

      const Routes = props => {
                  if (props.user) {
                     let isStudent=false;

                    const uid = props.user.uid;

                    firebase
                      .database()
                      .ref(`student/${uid}`)
                      .once("value")
                      .then(snapshot => {
                        if (snapshot.val().role === "student") {
                          console.log(snapshot.val());
                            isStudent=true
                        }
                      });

                    console.log(isStudent); //false
//i am getting the default value, if i remove that i get undefined

                  return (
                    <MainLayout>
                      <Switch>

                <StudentPublicRoute
                          {...props}
                          exact
                          restricted={true}
                          path="/student/login"
                          component={StudentLogin}
                        />
                        {isStudentamp;amp; <StudentPrivateRoute
                          {...props}
                          path="/student/studentdashboard"
                          exact
                          component={StudentDash}
                        />}
                 </Switch>
                    </MainLayout>
  

Ответ №1:

Метод once возвращает обещание, которое означает, что ваша функция будет выполняться асинхронно, поэтому функция console.log запускается до того, как вы получите ответ от firebase.

В вашем случае вам нужно будет сохранить значение isStudent в состоянии React.

Результат будет примерно таким:

 class YourComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isStudent: false};
  }
  ...

  firebase
  .database()
  .ref(`student/${uid}`)
  .once("value")
  .then(snapshot => {
  if (snapshot.val().role === "student") {
      this.setState({
        isStudent: true
    });
  }

}

  

Комментарии:

1. И вызов должен быть выполнен вне render(). Он должен сделать это внутри componentDidMount() или componentDidUpdate()

2. спасибо … 🙂 есть ли какой-нибудь способ сделать то же самое с компонентами без состояния?

3. Вам нужно будет обернуть логику доступа к базе данных в родительский компонент, который будет отображать ваш текущий компонент, передавая prop isStudent.

Ответ №2:

Это потому, что console.log(isStudent) выполняется до того, как isStudent=true.

Так будет всегда, поскольку вызов firebase занимает некоторое время. Рассмотрите также возможность использования компонента класса, а не функционального компонента, и используйте какой-нибудь фреймворк, такой как redux / saga или redux / thump, для асинхронных вызовов, подобных этому.

Возможно, вы могли бы попробовать с await / async, это может сработать.

Ваш код, как есть, никогда не будет работать.

Комментарии:

1. да, спасибо 🙂 .. есть ли какой-либо возможный способ, которым я могу изменить тот же компонент без состояния, потому что мои нижеприведенные компоненты зависят от … реквизит

2. функциональные компоненты являются самыми базовыми. Нет состояния, нет перехватов жизненного цикла, только реквизиты. Если вы хотите добиться этого без компонента класса, у вас будет содержащий компонент, выполняющий вызов, учитывая, что родительский компонент также является функциональным компонентом. Рассмотрите возможность пересмотра вашего дизайна, и я настоятельно рекомендую использовать redux / saga для асинхронных вызовов.