2017-09-08 53 views
1

在ReactJS我順利地通過道具從父到子組件,但是當調用回調函數,我注意到,沒有被執行ReactJS只能的setState卻拿不到狀態

  1. this.setState()後。
  2. 根本無法訪問this.state.*的值。

任何人都可以請幫忙嗎?

class RealTime extends Component { 
    constructor() { 
     super(); 
     this.state = { 
      mode: true, 
      marker_name: '', 
      sensor_id: '' 
     }; 
    } 

    handleInputChange(event) { 
     if(event.target.type === 'checkbox') { 
      alert("checked = " + event.target.checked); 
      this.setState({ 
       mode: event.target.checked 
      }); 
      alert("yy"); 
     } 
     else if(event.target.type === 'text') { 
      alert("event.target.name = " + event.target.name + " value = " + event.target.value); 
      this.setState({ 
       [event.target.name]: event.target.value 
      }); 
     } 
     else { 
      alert("Unknown input type = " + event.target.type); 
     } 

     alert("xx"); 
    } 

    handleSubmit(event) { 
     event.preventDefault(); 
     alert('handleSubmit'); 
     alert("submitted marker_name=" + this.state.mode); 
    } 

    render() { 
     return (
      <div className="animated fadeIn"> 
      <Row> 
       <Col xs="12"> 
       <Card> 
        <CardHeader> 
         Real Time Number of Customers in Shops 
        </CardHeader> 
        <CardBlock className="card-body"> 
         <MarkerForm mode={this.state.mode} marker_name={this.state.marker_name} sensor_id={this.state.sensor_id} 
           handleInputChange={this.handleInputChange} handleSubmit={this.handleSubmit}/> 
         <ConsoleEvent/> 
         <Canvas/> 
        </CardBlock> 
       </Card> 
       </Col> 
      </Row> 
      </div> 
     ) 
    } 
} 

class MarkerForm extends Component { 
    render() { 
     return (
      <Form inline onSubmit={this.props.handleSubmit}> 
       <FormGroup> 
        <Label className="switch switch-text switch-success switch-lg"> 
        <Input type="checkbox" className="switch-input" checked={this.props.mode} onChange={this.props.handleInputChange}/> 
        <span className="switch-label" data-on="On" data-off="Off"></span> 
        <span className="switch-handle"></span> 
        </Label> 
       </FormGroup> 
       <FormGroup> 
        <Input type="text" placeholder="Marker Name" name="marker_name" value={this.props.marker_name} onChange={this.props.handleInputChange} required/> 
       </FormGroup> 
       <FormGroup> 
        <Input type="text" placeholder="Sensor ID" name="sensor_id" value={this.props.sensor_id} onChange={this.props.handleInputChange} required/> 
       </FormGroup> 
       <FormGroup className="form-actions"> 
        <Button type="submit" color="primary" id="add-marker"><i className="fa fa-plus-square"></i> Add Marker</Button> 
        <Button type="button" color="danger" id="remove-marker"><i className="fa fa-minus-square"></i> Remove Marker</Button> 
       </FormGroup> 
      </Form> 
     ) 
    } 
    } 

在上面的代碼中,

alert("yy")永遠不會被執行。 alert("xx")也不是。這是在handleInput

而在handleSubmit()我只能看到提示框「handleSubmit」而非「submitted marker_name=

+1

無論是將'this'綁定到每個處理程序或使用箭頭函數。問題在於'this'在你的函數中有一個不同的上下文,所以你不能在不正確的對象上調用'setState'。 – Chris

+0

你是否將函數綁定到了你的組件? – Nocebo

回答

2

您應該使用bind的功能。這是因爲this有不同的語境,不綁定:

constructor() { 
    super(); 
    this.state = { 
     mode: true, 
     marker_name: '', 
     sensor_id: '' 
    }; 

    this.handleSubmit = this.handleSubmit.bind(this) 
} 
0

試試這個:

handleInputChange = (event) => { 
     if(event.target.type === 'checkbox') { 
      alert("checked = " + event.target.checked); 
      this.setState({ 
       mode: event.target.checked 
      }); 
      alert("yy"); 
     } 
     else if(event.target.type === 'text') { 
      alert("event.target.name = " + event.target.name + " value = " + event.target.value); 
      this.setState({ 
       [event.target.name]: event.target.value 
      }); 
     } 
     else { 
      alert("Unknown input type = " + event.target.type); 
     } 

     alert("xx"); 
    } 

使用arrow功能的功能結合到你的組件,而不是寬鬆的背景下this。您可以在這裏閱讀更多關於它們的信息:https://medium.com/@machnicki/handle-events-in-react-with-arrow-functions-ede88184bbb。或者,您可以像建議的其他答案那樣在構造函數中綁定函數。但是,如果稍後有幾項功能,則會意識到使用arrow功能的方法更爲平滑和清晰。

0

的問題是,這當你將它傳遞給組件不同的環境。您需要綁定到你的函數在構造函數中:

class RealTime extends Component { 
    constructor() { 
     super(); 
     this.state = { 
      mode: true, 
      marker_name: '', 
      sensor_id: '' 
     }; 

    this.handleInputChange = this.handleInputChange.bind(this); 
    // same for other functions 
} 
0

你需要初始化內部custructor手柄功能,使您可以使用this: 嘗試一下本作綁定:

constructor(props){ 
this.state = { 
     mode: true, 
     marker_name: '', 
     sensor_id: '' 
}; 
this.handleInputChange = (event) => { 
    if(event.target.type === 'checkbox') { 
     alert("checked = " + event.target.checked); 
     this.setState({ 
      mode: event.target.checked 
     }); 
     alert("yy"); 
    } 
    else if(event.target.type === 'text') { 
     alert("event.target.name = " + event.target.name + " value = " + event.target.value); 
     this.setState({ 
      [event.target.name]: event.target.value 
     }); 
    } 
    else { 
     alert("Unknown input type = " + event.target.type); 
    } 

    alert("xx"); 
}; 

this.handleSubmit = (event) => { 
    event.preventDefault(); 
    alert('handleSubmit'); 
    alert("submitted marker_name=" + this.state.mode); 
}; 
}