2017-01-12 9 views
1

Ich habe folgendes:Reagieren Kraft componentDidMount

import React from 'react'; 
import axios from 'axios'; 

class FirstName extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      submitted: false 
     }; 
    } 
    getName() { 
     var name = this.refs.firstName.value; 
     this.setState(function() { 
      this.props.action(name); 
     }); 
    } 
    handleSubmit (e) { 
     e.preventDefault(); 
     this.setState({ submitted: true }, function() { 
      this.props.actionID(2); 
      this.props.activeNav('color'); 
     }); 
    } 
    render() { 
     return (
      <div> 
       <h2>tell us your first name</h2> 
       <form> 
        <input 
         type="text" 
         ref="firstName" 
         onChange={this.getName.bind(this)} 
        /> 
        <div className="buttons-wrapper"> 
         <button href="#">back</button> 
         <button onClick={this.handleSubmit.bind(this)}>continue</button> 
        </div> 
       </form> 
      </div> 
     ); 
    } 
}; 

class PickColor extends React.Component { 
    backToPrevious (e) { 
     e.preventDefault(); 
     this.props.actionID(1); 
     this.props.activeNav('name'); 
    } 
    goToNext (e) { 
     e.preventDefault(); 
     this.props.actionID(3); 
     this.props.activeNav('design'); 
     this.props.displayIconsHolder(true); 
    } 
    getColorValue(event) { 
     this.props.color(event.target.getAttribute("data-color")); 
    } 
    render() { 
     var colors = ['red', 'purple', 'yellow', 'green', 'blue'], 
      colorsLink = []; 

     colors.forEach(el => { 
      colorsLink.push(<li 
           data-color={el} 
           key={el} 
           onClick={this.getColorValue.bind(this)} 
           ref={el}> 
            {el} 
          </li> 
      ); 
     }); 

     return (
      <section> 
       <ul> 
        {colorsLink} 
       </ul> 
       <button onClick={this.backToPrevious.bind(this)}>back</button> 
       <button onClick={this.goToNext.bind(this)}>continue</button> 
      </section> 
     ); 
    } 
} 

class ConfirmSingleIcon extends React.Component { 
    goBack() { 
     this.props.goBack(); 
    } 
    confirmCaptionandIcon (event) { 
     var optionID = event.target.getAttribute("data-option-id"), 
      name = event.target.getAttribute("data-option-name"); 
     this.props.setOptionID(optionID); 
     this.props.setIcon(1, name, optionID, false); 
    } 
    goNext() { 
     this.props.goNext(); 
    } 
    render() { 
     console.log(this.props.currentState); 
     var options = [], 
      that = this; 
     this.props.iconOptionsList.forEach(function(el){ 
      options.push(<li onClick={that.confirmCaptionandIcon.bind(that)} key={el.option} data-option-name={el.option} data-option-id={el.id}>{el.option}</li>); 
     }); 
     return (
      <div> 
       <h2>Choose your caption</h2> 
       <h3> 
        {this.props.selectedIcon} 
       </h3> 
       <ul> 
        {options} 
       </ul> 
       <button onClick={this.goBack.bind(this)} >back</button> 
       <button onClick={this.goNext.bind(this)} >confirm</button> 
      </div> 
     ); 
    } 
} 

class ConfirmCaption extends React.Component { 
    handleClick() { 
     var currentState = this.props.currentState; 
     this.props.setIcon(currentState.icon_ID, currentState.selectedIcon, currentState.option_ID, true); 
     this.props.setIconVisiblity(true); 
     this.props.setIconListVisiblity(false); 
    } 
    render() { 
     console.log(this.props.currentState); 
     return (
      <div> 
       <p onClick={this.handleClick.bind(this)}>confirm icon and caption</p> 
      </div> 
     ); 
    } 
} 

class ChooseIcon extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      icons: [], 
      iconList: true, 
      confirmIcon: false, 
      confirmCaption: false, 
      selectedIconOptions: '', 
      icon_ID: '', 
      option_ID: '', 
      selectedIcon: '' 
     }; 
     this.setOptionID = this.setOptionID.bind(this); 

     this.setIconVisiblity = this.setIconVisiblity.bind(this); 
     this.setIconListVisiblity = this.setIconListVisiblity.bind(this); 
    } 
    setOptionID (id) { 
     this.setState({ option_ID: id }) 
    } 
    setIconVisiblity (onOff) { 
     this.setState({ confirmIcon: onOff }) 
    } 
    setIconListVisiblity (onOff) { 
     this.setState({ iconList: onOff }) 
    } 
    componentDidMount() { 
     var url = `http://local.tshirt.net/get-options`; 
     axios.get(url) 
      .then(res => { 
       this.setState({ icons:res.data.icons }); 
     }); 
    } 
    handleClick (event) { 
     var iconId = event.target.getAttribute("data-icon-id"), 
      that = this; 
     this.state.icons.forEach(function(el){ 
      if(el.id == iconId){ 
       that.setState(
        { 
         confirmIcon: true, 
         iconList: false, 
         selectedIcon: el.name, 
         icon_ID: iconId, 
         selectedIconOptions: el.option 
        } 
       ); 
      } 
     }); 
    } 
    goBack() { 
     this.setState(
      { 
       confirmIcon: false, 
       iconList: true 
      } 
     ); 
    } 
    goNext() { 
     this.setState(
      { 
       confirmIcon: false, 
       iconList: false, 
       confirmCaption: true 
      } 
     ); 
    } 
    render() { 
     var icons = []; 
     this.state.icons.forEach(el => { 
      icons.push(<li data-icon-id={el.id} onClick={this.handleClick.bind(this)} key={el.name}>{el.name}</li>); 
     }); 
     return (
      <div> 
       {this.state.iconList ? <IconList icons={icons} /> : ''} 
       {this.state.confirmIcon ? <ConfirmSingleIcon goBack={this.goBack.bind(this)} 
                  goNext={this.goNext.bind(this)} 
                  setIcon={this.props.setIcon} 
                  selectedIcon={this.state.selectedIcon} 
                  iconOptionsList ={this.state.selectedIconOptions} 
                  setOptionID={this.setOptionID} 
                  currentState={this.state} /> : ''} 

       {this.state.confirmCaption ? <ConfirmCaption currentState={this.state} 
                  setIcon={this.props.setIcon} 
                  setIconVisiblity={this.setIconVisiblity} 
                  setIconListVisiblity={this.setIconListVisiblity} /> : ''} 
      </div> 
     ); 
    } 
} 

class IconList extends React.Component { 
    render() { 
     return (
      <div> 
       <h2>Pick your icon</h2> 
       <ul> 
        {this.props.icons} 
       </ul> 
      </div> 
     ); 
    } 
} 

class Forms extends React.Component { 
    render() { 
     var form; 
     switch(this.props.formID) { 
      case 1: 
       form = <FirstName action={this.props.action} actionID={this.props.switchComponent} activeNav={this.props.activeNav} /> 
       break; 
      case 2: 
       form = <PickColor displayIconsHolder={this.props.seticonsHolder} color={this.props.colorVal} actionID={this.props.switchComponent} activeNav={this.props.activeNav} /> 
       break; 
      case 3: 
       form = <ChooseIcon setIcon={this.props.setOptionA} /> 
       break; 
     } 
     return (
      <section> 
       {form} 
      </section> 
     ); 
    } 
} 

export default Forms; 

„ChooseIcon“ ist eine Komponente, die 3-mal gewöhnen wird daher jedes Mal wenn ich es bekommen Ich brauche seinen Zustand zurück zu bringen, als wäre es das erste Mal war, .

Idealerweise würde ich dieses Ajax-Aufruf jedes Mal machen müssen:

componentDidMount() { 
    var url = `http://local.tshirt.net/get-options`; 
    axios.get(url) 
     .then(res => { 
      this.setState({ icons:res.data.icons }); 
    }); 
} 

ist es eine Möglichkeit, manuell componentDidMount anrufen vielleicht von einer übergeordneten Komponente?

Antwort

1

Wenn Sie die ChooseIcon Komponente 3 mal in der gleichen übergeordneten Komponente verwenden, würde ich vorschlagen, dass Sie die Ajax in componentDidMount der übergeordneten Komponente wie dies zu tun (exaclty, wie Sie in Ihrem Beispiel haben, in Form von Code)

componentDidMount() { 
    var url = `http://local.tshirt.net/get-options`; 
    axios.get(url) 
     .then(res => { 
      this.setState({ icons:res.data.icons }); 
    }); 
} 

und dann diese Daten bis auf die

render() { 
    return (
    //do your stuff 
    <ChooseIcon icons={this.state.icons}/> 
) 
} 

danach

ChooseIcon Komponente zu übergeben Sie nur die empfangenen Requisiten in Ihrem ChooseIcon Komponente, für tha benötigt einstellen t Sie müssen nur eine Zeile im Konstruktor ändern:

constructor(props) { 
    super(props); 
    this.state = { 
     icons: props.icons, // Changed here! 
     iconList: true, 
     confirmIcon: false, 
     confirmCaption: false, 
     selectedIconOptions: '', 
     icon_ID: '', 
     option_ID: '', 
     selectedIcon: '' 
    }; 
    this.setOptionID = this.setOptionID.bind(this); 

    this.setIconVisiblity = this.setIconVisiblity.bind(this); 
    this.setIconListVisiblity = this.setIconListVisiblity.bind(this); 
} 
1

Die übergeordnete Komponente kann einen Verweis verwenden, um die Funktion direkt aufzurufen.

Der Versuch, diese Funktion zu erzwingen, fühlt sich jedoch an wie ein Geruch. Vielleicht würde dieses Problem gelöst, wenn man den Zustand höher im Komponentenbaum anhebt. Auf diese Weise teilt die übergeordnete Komponente ChooseIcon mit, was angezeigt werden soll, und componentDidMount muss nicht erneut aufgerufen werden. Außerdem nehme ich an, dass der Ajax-Aufruf auch einmal auftreten kann.

5

React behandelt Komponente Lebenszyklus durch key Attribut. Zum Beispiel:

<ChooseIcon key={this.props.formID} setIcon={this.props.setOptionA} /> 

Also jedes Mal, wenn Ihr key (es kann alles, was Sie sein mögen, aber einzigartig) geändert Komponente aushängen und wieder montieren, damit Sie leicht componentDidMount Rückruf kontrollieren können.

Verwandte Themen