Как вызвать data setState для возврата в ответ? - PullRequest
0 голосов
/ 28 ноября 2018

Я могу вызвать данные в console.log(this.state.eventUser); рендеринг return и отображение всех данных в eventUser.Но когда я пытаюсь вызвать console.log(this.state.eventUser._id);, это показывает ошибку этого Uncaught TypeError: Cannot read property '_id' of undefined.Как я могу решить эту проблему?

    componentDidMount(){
        Tracker.autorun(() => {
            Meteor.subscribe('allUsers');
            const userId = this.props.location.state.event.userID;
            const eventUser = Meteor.users.findOne({_id: userId});
            this.setState({ eventUser });
        });
    }

    render(){
        return(
            <div>
                {console.log(this.state.eventUser._id)}
            </div>
        );
    }

Ответы [ 5 ]

0 голосов
/ 28 ноября 2018

Впервые, когда ваш компонент будет рендериться, если у вас есть знания о хуках жизненного цикла реагирования, после конструктора будет запущен render method, а затем хук componentDidMount.поэтому для первого рендера eventUser не определено, затем после componentDidMount состояние будет выполнено.

Итак, решение таково:

  • Сначала не вставляйте console.log вJSX, лучше поставить его перед return.
  • Вторая первая проверка, определен ли объект, затем вернуть ваши данные

Код:

render(){
       const { eventUser } = this.state;

        // if eventUser is defined then log it
        {eventUser && console.log(eventUser._id)}

        // or you can add very simple load state
       if(!eventUser) return <h1>Loading....</h1>

    return(
        <div>
            {probably info about user }
        </div>
    );
}
0 голосов
/ 28 ноября 2018

componentDidMount сработает после того, как компонент уже смонтирован (как следует из названия).В момент, когда он достигает вложенного оператора, состояние еще не было установлено.

Я не уверен, почему вы используете console.log внутри вашего результата рендеринга, но если вы действительно хотите отобразить идентификатор пользователя, условный рендеринг - ваш друг: {this.state.eventUser && this.state.eventUser._id}

0 голосов
/ 28 ноября 2018

Возможно, в какой-то момент this.state.eventUser в рендере не определено.

Попробуйте это

{this.state.eventUser && console.log(this.state.eventUser._id)
0 голосов
/ 28 ноября 2018

Похоже, что к моменту запуска функции render() пользователь еще не был сохранен в состоянии компонента.

Чтобы это исправить, добавьте конструктор к вашему компоненту, в котором вы определяете eventUser как пустой объект.

class MyClass extends Component {

  constructor(props) {
    super(props);

    this.state {
      eventUser: {}
    };
  }

  componentDidMount() {
    Tracker.autorun(() => {
        Meteor.subscribe('allUsers');
        const userId = this.props.location.state.event.userID;
        const eventUser = Meteor.users.findOne({_id: userId});
        this.setState({ eventUser });
    });
  }

  render(){
    console.log(this.state.eventUser._id)
    return(
      <div>My Test Page</div>
    );
  }
}

Надеюсь, это поможет!

0 голосов
/ 28 ноября 2018

Вы не можете использовать console.log внутри JSX, не заключив в него {} Попробуйте код ниже

render(){
    return(
        <div>
            {put javascript here}
        </div>
    );
}

Редактировать:

Ваш код выполняет запрос наБаза данных асинхронная. Вам нужно дождаться ее завершения.Ниже приведена реализация async / await (es7 + функции javascript)

Попробуйте код ниже

 componentDidMount(){
            Tracker.autorun(async () => {
                Meteor.subscribe('allUsers');
                const userId = this.props.location.state.event.userID;
                const eventUser = await Meteor.users.findOne({_id: userId});
                this.setState({ eventUser });
            });
        }
...