【问题标题】:How to use constructor value outside constructor?如何在构造函数之外使用构造函数值?
【发布时间】:2018-02-20 16:52:05
【问题描述】:

在我的组件中,我收到一个数组对象(仅限 3 个对象)。我想单独显示它们,还想为它们添加一个onClick 事件,以便当用户单击它们中的任何一个时,我可以为每种情况呈现不同的组件。
现在的问题是我正在访问构造函数中的变量,而组件的其余部分在该范围之外。这种情况该怎么办??

import React, { Component } from 'react';
import '../App.css';
import {withRouter} from 'react-router';
import MonthToDate from './monthtodate';
import QuarterToDate from './quartertodate';
import YearToDate from './yeartodate';
class Dashboard extends Component {

  constructor(props){
    super(props);
    if(this.props.location && this.props.location.state){
      console.log(this.props.location.state.values.o1)
      var o1=this.props.location.state.values.o1;
      var o2=this.props.location.state.values.o2;
      var o3=this.props.location.state.values.o3;
    }
  }
  callMonth = () => { this.props.history.push({pathname: '/monthtodate'}) };
  callQuarter = () => { this.props.history.push({pathname: '/quartertodate'}) };
  callYear = () => { this.props.history.push({pathname: '/yeartodate'}) };

  render() {
    return (
      <div>
        <div onClick:{this.callMonth}>
          <p>MonthToDate: {o1}</p>
        </div>
        <div onClick:{this.callQuarter}>
          <p>QuarterToDate: {o2}</p>
        </div>
        <div onClick:{this.callYear}>
          <p>YearToDate: {o3}</p>
        </div>
      </div>
    );
  }
}

export default Dashboard;          

注意: 执行 {this.props.location.state.values.o1} 在 return 内部不起作用,因为它需要 if 条件 idk 为什么。 经过多次谷歌搜索,我开始知道反应中没有类变量。取而代之的是 Context,但官方文档说 这是一个实验性 API,它可能会在未来的 React 版本中中断

上面的组件被Login组件调用,即login.js,如下:

import React, { Component } from 'react';
import '../App.css';
import Dashboard from './dashboard';
import {withRouter} from 'react-router';
var axios = require('axios');

class Login extends Component {
  constructor(props){
    super(props);
    //this.state = {isToggleOn: true};
    this.loadDashboard = this.loadDashboard.bind(this);
    this.handleOnSubmit = this.handleOnSubmit.bind(this);
    this.setData = this.setData.bind(this);
    this.state = {values:null}
  }
  setData(data){
    this.setState({values:data});
    //console.log(data);
    this.props.history.push({
      pathname: '/dashboard',
      state: { values: data }
  })
  }
  loadDashboard(token){
    console.log(token);
    axios({
      method:'get',
      url:'http://localhost:3000/api/dashboard',
      headers: {
        Authorization: `Bearer ${token}`,
      },
    })
     .then( (response) => {
      // console.log(response.data);
      //  this.props.history.push('/dashboard',this.state.values);
       this.setData(response.data);
     })
     .catch(function (error) {
       console.log("Error in loading Dashboard "+error);
     });
  }

  handleOnSubmit = () => {
     //console.log("submittwed");
     axios({
       method:'post',
       url:'http://localhost:3000/authenticate',
       data: {
         email: 'test@mail.com',
         password: 'apple'
       },
     })
      .then((response) => {
        var token = response.data.auth_token;
      //  console.log(token);
        this.loadDashboard(token);
      })
      .catch(function (error) {
        console.log("Error in login "+error);
      });
   }

  render() {
    return (
      <div>
         Username: <input type="email" name="fname" /><br />
         Password: <input type="password" name="lname" /><br />
         <button onClick={this.handleOnSubmit}>LOG IN</button>     
      </div>
    );
  }
}

export default Login;       
  • 如何在整个类中传递变量。 (注意:我以后不想更改它,只想显示它所以不要REDUX)。
  • 有没有更好的方法来解决这个问题?

【问题讨论】:

  • 您应该在 componentDidMount 或 componentWillMount 中将来自构造函数之外的道具的值分配给状态或类变量,或者更好,因为@Knut 说直接在渲染中使用它,条件是您在构造函数中使用过

标签: reactjs ecmascript-6


【解决方案1】:

您可以如下使用本地组件状态:

constructor(props){
    super(props);
    if(this.props.location && this.props.location.state){
      this.state = {
        o1 : this.props.location.state.values.o1,
        o2 : this.props.location.state.values.o2,
        o3 : this.props.location.state.values.o3
      }
    }
  }

然后在您的渲染或您需要的任何方法中使用它,如下所示:

render() {
    return (
      <div>
        <div onClick={()=>{this.callMonth()}}>
          <p>MonthToDate: {this.state.o1}</p>
        </div>
        <div onClick={()=>{this.callQuarter()}}>
          <p>QuarterToDate: {this.state.o2}</p>
        </div>
        <div onClick={()=>{this.callYear()}}>
          <p>YearToDate: {this.state.o3}</p>
        </div>
      </div>
    );
  }

希望这会有所帮助。

【讨论】:

  • 它给了我这个错误:Error in loading Dashboard Invariant Violation: Objects are not valid as a React child (found: object with keys {invoiceAmt, title}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Dashboard.
  • 您能否将调试器作为第一个语句放在构造函数中的 if 块中,然后将光标悬停在“this.props.location.state.values.o1”上并确认您在那里找到的内容。 @mwCoder
  • 该值正在传递给我检查过的 if 语句。当我记录输出时,它会显示对象。以前我遇到过this 问题,因此我必须实施该 if 块。
  • 那么你说我要显示对象是什么意思,当然你不能直接在render中渲染一个对象。
  • 你想如何显示对象?
【解决方案2】:

您应该使用this 关键字来将对象存储在您的class 中。
所以你可以做这样的事情,例如:

constructor(props){
    super(props);
    if(this.props.location && this.props.location.state){
      console.log(this.props.location.state.values.o1)
      this.o1=this.props.location.state.values.o1;
      this.o2=this.props.location.state.values.o2;
      this.o3=this.props.location.state.values.o3;
    }
  }

并以相同的方式访问它:

<div onClick:{this.callMonth}>
   <p>MonthToDate: {this.o1}</p>
</div>

话虽如此,我认为您应该重新考虑这种方法,并可能直接从 props 访问这些值,或者创建一个 state 并将它们存储在那里。
无论哪种方式,您都应该更新 componentWillReceiveProps life cycle method 中的对象

【讨论】:

  • 它给了我这个错误Objects are not valid as a React child (found: object with keys {invoiceAmt, title}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Dashboard.
猜你喜欢
  • 2016-07-16
  • 2021-03-18
  • 2023-04-02
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多