开发者问题收集

在状态中存储对象时,ReactJS 在渲染时出现获取类型错误

2017-05-24
379

我对 React 还很陌生,我试图从服务器获取一个对象(会话)并使用表单对其进行编辑,在进行更改后,使用帖子将其存储到服务器。

我制作了一个组件,它从服务器获取数据并将其存储到状态中。

问题是渲染部分出现错误,因为它可能还不知道状态对象的子字段。我指的是“session.name”和其他几个字段,但这会出现错误。( TypeError :this.state.session 为 null[更多信息])

class SessionFirstTab extends React.Component {
    constructor() {
        super();
        this.state = { 
            session: null,
            statechanged: false
        };  
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.getSessionData = this.getSessionData.bind(this)

    }

    componentDidMount() {
        this.getSessionData()
    }

    getSessionData() {
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", 'application/x-www-form-urlencoded');
        myHeaders.append("x-access-token", 'eyJhbGciOiJIUzI1....');
        myHeaders.append("userid", "5904ab94835a710868d19fa2");
        myHeaders.append("id", this.props.sessionid);

        var myInit = { method: 'GET',
               headers: myHeaders,
               mode: 'cors',
               cache: 'default' };


       fetch('http://localhost:3000/api/session',myInit) 
      .then(function(response) {  
          if (response.status !== 200) {  
            console.log('Looks like there was a problem. Status Code: ' +  
              response.status); 
            return;  
          }
        //   Examine the text in the response  
         response.json().then(function(data) {  
         data => this.setState({session: data});

          });  
        }  
      )  
      .catch(function(err) {    
        console.log('Fetch Error', err);  
      });



    } //////////////END getSessionInfo


    handleChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

        this.setState({ statechanged: true});
        this.setState({session: {[name]: value}});
    }


    handleSubmit(event) {
    // console.log(this.state.session.name);
        event.preventDefault();
    }



    render() {
        return (

     <article className="article">
    <h2 className="article-title">Edit Session </h2>

    <section className="box box-default">
      <div className="box-body padding-xl">

        <section className="box box-default">
          <div className="box-body no-padding">
           <Tabs>
    <Tab label="Properties" >
      <div style={styles}>

       <form role="form" onSubmit={this.handleSubmit}>





          <div className="divider divider-lg" />
    <div className="row">

      <div className="col-xl-6">
        <div className="box box-default">
          <div className="box-body">
            <div className="icon-box ibox-center">
              <div className="ibox-icon">
                <a href="javascript:;"><i className="material-icons">settings</i></a>
              </div>
              <h3>General</h3>
               <div className="form-group">
             <TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name"  floatingLabelFixed defaultValue={this.state.session.name} onChange={this.handleChange}/><br />
          </div>
2个回答

我认为您唯一需要做的就是检查 session 是否为 null。 我通常使用两种方法,具体取决于我需要什么。

方法 1:

如果有 session,则呈现 session.name,否则呈现空字符串。

<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name"  floatingLabelFixed defaultValue={this.state.session !== null ? this.state.session.name : ''} onChange={this.handleChange}/>

这种方式迫使您还要检查处理程序内部。对于您来说,您必须检查 handleChange 内部以及 handleSummit 内部。 所以在我看来,您应该尝试第二种方法。

方法 2:

如果有 session,则呈现表单,否则呈现一些加载图

if(this.state.session){
  return (
    <form role="form" onSubmit={this.handleSubmit}>
      ... your staff here   
    </form>
  );
} else {
  return (
    <div>
      We are waiting for the session
    </div>
  );
}

特别是,我不会将整个 session 存储在状态中,而只会存储我需要的属性。我的意思是,我会存储 this.state.name。仅出于语义和责任方面的考虑。为什么?我假设您的会话包含许多组件不需要知道的内容,因此它不应该存在。但我们可以就此进行很好的讨论。

希望它有所帮助,如果您觉得需要澄清,请告诉我,我会提供帮助。

Facundo La Rocca
2017-05-24

您只需处理会话为空的情况。一个简单的解决方案是:

render() {
    const session_name = this.state.session.name || '';
        return (

     <article className="article">
    <h2 className="article-title">Edit Session </h2>

    <section className="box box-default">
      <div className="box-body padding-xl">

        <section className="box box-default">
          <div className="box-body no-padding">
           <Tabs>
    <Tab label="Properties" >
      <div style={styles}>

       <form role="form" onSubmit={this.handleSubmit}>





          <div className="divider divider-lg" />
    <div className="row">

      <div className="col-xl-6">
        <div className="box box-default">
          <div className="box-body">
            <div className="icon-box ibox-center">
              <div className="ibox-icon">
                <a href="javascript:;"><i className="material-icons">settings</i></a>
              </div>
              <h3>General</h3>
               <div className="form-group">
             <TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name"  floatingLabelFixed defaultValue={session_name} onChange={this.handleChange}/><br />
          </div>
Chase DeAnda
2017-05-24