2017-06-16 9 views
-1

私はReactとReact Routerを使ってCRUDアプリケーションを作成しようとしていますが、私のように状態が子コンポーネントに渡されない理由を理解できませんそれを期待する。 editルートをヒットすると、Editコンポーネントがレンダリングされます。このコンポーネントは、データベースから必要な子猫を取得し、既存の子猫を編集するか、新しい子コンポーネントを追加するために使用されるフォームコンポーネントに情報を送信します。ここで 状態を子コンポーネントに渡すと小道具として機能しません

は編集コンポーネントです:

import React, { Component } from 'react'; 
import axios from 'axios'; 
import { match } from 'react-router-dom'; 
import Form from './Form'; 


export default class Edit extends Component { 
    constructor(props) { 
     super(props) 

     this.state = {} 
    } 

    componentDidMount() { 
     axios.get(`/updateKitten/${this.props.match.params.id}`) 
     .then(res => { 
      const kitten = res.data 
      this.setState({ kitten }) 
      console.log(this.state.kitten.name) //Sammy, or something 
     }) 
     .catch(err => console.log(err)) 
    } 

    render() { 
     return (
       <Form 
        name={this.state.kitten.name} // throws error or undefined 
        description={this.state.kitten.description} //throws error or undefined 
        route={this.props.match.params.id} 
       /> 
     ) 
    } 
} 

編集コンポーネントは、このフォームコンポーネントに名前、説明、およびルートを渡します。

import React, { Component } from 'react'; 
import axios from 'axios'; 

export default class Add extends Component { 
    constructor(props) { 
    super(props) 

    this.state = { name: this.props.name, description: this.props.description} 

    this.handleChange = this.handleChange.bind(this); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 

    handleChange(e) { 
    const name = e.target.name; 
    const value = e.target.value; 

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

    handleSubmit(e) { 
    axios.post(`/addKitten/${this.props.route}`, this.state) 
     .then(this.setState({ name: '', description: '' })) 
    e.preventDefault(); 
    } 

    render() { 
    return (
     <form onSubmit={this.handleSubmit}> 
     <label>Name</label> 
     <input type='text' name="name" value={this.state.name} 
     onChange={this.handleChange}/> 
     <label>Description</label> 
     <input type='text' name="description" value={this.state.description} 
      onChange={this.handleChange}/> 
     <input type='submit' value='Submit' /> 
     </form> 
    ) 
    } 
} 

そして、私は次のエラーを取得:

bundle.js:28950 Uncaught TypeError: Cannot read property 'name' of undefined

から、その情報をprとして送信しようとしていますopsをFormコンポーネントに追加します。

私は間違っていますか?

答えて

0

2つのこと、

まず:あなたの編集コンポーネントでは、子猫の状態を初期化していないと、あなたは、APIの結果に基づいて、それを設定しています。ただし、コンポーネントが呼び出された後にcomponentDidMountが呼び出され、DOMは一度レンダリングされ、最初にthis.state.kitten.nameまたはthis.state.kitten.descriptionという値が見つからなかったときにレンダリングされます。

APIの後は、子猫の状態を成功させるだけです。したがって、レンダリング中にチェックするだけです。

第2の:setState機能の後にconsole.log(this.state.kitten.name)があります。しかし、setState is asynchronous。この質問を参照してください:

Change state on click react js

ので、あなたが

あなたのコードは

export default class Edit extends Component { 
    constructor(props) { 
     super(props) 

     this.state = {} 
    } 

    componentDidMount() { 
     axios.get(`/updateKitten/${this.props.match.params.id}`) 
     .then(res => { 
      const kitten = res.data 
      this.setState({ kitten }. function() { 
        console.log(this.state.kitten.name) //Sammy, or something 
      }) 

     }) 
     .catch(err => console.log(err)) 
    } 

    render() { 
     return (
       <Form 
        name={this.state.kitten.name || '' } 
        description={this.state.kitten.description || ''} 
        route={this.props.match.params.id} 
       /> 
     ) 
    } 
} 
のようになります。SETSTATEコールバックではconsole.logを指定する必要があります
0

編集コンポーネントを初めて読み込むときには、kittenはありません。したがって、エラー。

あなたがする必要があるのは、empty子猫を作成することです。編集コンポーネントで...

this.state = { kitten: {name:''} } 

これは、あなたのコンポーネントの最初のマウント/レンダリングで、子猫の名前を空の文字列に設定します。

関連する問題