【问题标题】:React - Using Props outside of RenderReact - 在渲染之外使用道具
【发布时间】:2019-02-18 01:54:42
【问题描述】:

我正在尝试将 UserId 发布到数据库,但 Id 作为道具传递。当我在渲染方法中输入 this.props.userId 时,它会显示所需的信息,但是当我尝试将其合并到渲染函数上方的函数中时,我得到空值。我花了几个小时查看其他帖子并尝试我所能做的一切都无济于事。

App.js 代码

import axios from 'axios'
import {
  BrowserRouter as Router,
  Route,
  Redirect,
} from 'react-router-dom'
import Home from "./pages/Home";
import MyEvents from "./pages/MyEvents"
import Signup from "./pages/Signup";
import Login from "./pages/Login";
import Navbar from "./components/Navigation/Navigation";
import "./App.css"


class App extends Component {
  constructor() {
    super()
    this.state = {
      loggedIn: false,
      username: null,
      userId: null,
    }

    this.getUser = this.getUser.bind(this)
    this.componentDidMount = this.componentDidMount.bind(this)
    this.updateUser = this.updateUser.bind(this)
  }

  componentDidMount() {
    this.getUser()
  }

  updateUser (userObject) {
    this.setState(userObject)
  }

  getUser() {
    axios.get('/api/users/').then(response => {
      console.log('Get user response: ')
      console.log(response.data)
      if (response.data.user) {
        console.log('Get User: There is a user saved in the server session: ')

        this.setState({
          loggedIn: true,
          username: response.data.user.username,
          userId: response.data.user._id
        })
      } else {
        console.log('Get user: no user');
        this.setState({
          loggedIn: false,
          username: null,
          userId: null
        })
      }
    })
  }

  render() {
    return (
      <div className="App">

        <Navbar updateUser={this.updateUser} loggedIn={this.state.loggedIn} />
        {/* greet user if logged in: */}
        {this.state.loggedIn &&
          <p>You are logged in, {this.state.username}, userId: {this.state.userId}!!!!</p>
        }
        {/* Routes to different components */}
        <Route
          exact path="/home"
          render = {() => 
            <Home userId = {this.state.userId} />
          }
          />

Home.js 代码

import React, { Component } from "react";
import API from "../utils/API";
class Events extends Component {
  state = {
    events: [],
    search: "",
    selector: "",
    input:""
    };


  attendEvent = show => {
    API.attendConcert({
      userId: this.props.userId,
      concertId: show.id,
      artist: show.performance[0].artist.displayName,
      venue: show.venue.displayName,
      date: show.start.date,
      time: show.start.time,
      city: show.venue.metroArea.displayName,
      latitude: show.venue.lat,
      longitude: show.venue.lng,
    })
    .then(res => window.location.href = "/concerts/" + res.data._id)
    .catch(err => console.log(err))
  }

  handleRadioChange = event => {
    this.setState({
      selector: event.target.value
    });
  }


  render() {
    return (<>
      <Container>
        <Row>
          <Col size="md-12">
<p>Hi {this.props.userId}</p>

API.JS 代码

import axios from "axios";

export default {
    attendConcert: function(eventData) {
        return axios.post("/api/concerts", eventData);
    },
    getConcert: function(id) {
        return axios.get("/api/concerts/" + id);
    }
}

注意:删除了一些代码行以减少呈现的代码量,但如果想查看所有内容,请告诉我。

【问题讨论】:

  • 是的,用户 ID 起初将为空,因为您首先定义了空用户 ID 状态,稍后当您的 api 引发响应时​​,它将设置状态(更新)。但是在您的 api 引发响应之前,您的 routh 路径已经被渲染。所以你可以在 userid 有值之后渲染路径。

标签: reactjs react-router-dom react-props


【解决方案1】:

这是一个范围问题:

API.attendConcert({
      userId: this.props.userId,
      concertId: show.id,
      artist: show.performance[0].artist.displayName,
      venue: show.venue.displayName,
      date: show.start.date,
      time: show.start.time,
      city: show.venue.metroArea.displayName,
      latitude: show.venue.lat,
      longitude: show.venue.lng,
    })

this 在该上下文中指的是您正在构建的对象文字,而不是组件。

声明一个变量来保存userId 的值,然后在对象字面量中使用该值,如下所示:

const userId = this.props.userId
API.attendConcert({
     userId: userId,
      concertId: show.id,
      artist: show.performance[0].artist.displayName,
      venue: show.venue.displayName,
      date: show.start.date,
      time: show.start.time,
      city: show.venue.metroArea.displayName,
      latitude: show.venue.lat,
      longitude: show.venue.lng,
    })

【讨论】:

    【解决方案2】:

    正如 Binod 评论的那样,您收到 userId: null,因为您最初在状态下将其设置为 null,并且由于异步功能,您的代码在 app.js 中的 API 调用有时间返回之前执行。我建议在Asynchronous Javascript 上查看此资源。

    您的&lt;Home /&gt; 组件的props 将在您收到响应时更新,并将被传递,因此您需要做的是确保在传递userId 之前不调用attendEvent()。您当前的代码目前没有显示它是如何被调用的,但我认为它在另一个 componentDidMount 中。尝试改用componentDidUpdate() 并检查是否props.userId !== null,然后进行API 调用attendConcert

    希望这会有所帮助,如果您还有任何问题,请告诉我!

    【讨论】:

      【解决方案3】:

      您可以尝试从 componentDidMount() 调用该函数。因为一切都是异步的。您的状态未在父组件中设置,并且在子组件中用作道具。我也面临同样的问题。道具在 child 的 render() 中渲染,但在其他任何地方都没有。

      您也可以使用 localStorage。

      试试这个,在路由到主组件之前放置一个空检查。

         {this.state.userId ?
         <Route
            exact path="/home"
            render = {() => 
              <Home userId = {this.state.userId} /> : null}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-23
        • 2017-06-02
        • 1970-01-01
        • 2023-04-01
        • 2020-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多