2017-05-10 1 views
1

간단히 손자 구성 요소에서 상위 구성 요소 함수를 호출하려고합니다. 여기 하위 구성 요소의 하위에서 호출 부모 함수가 반응합니다.

var ReactDOM = require('react-dom'); 
var React = require('react'); 

class Button extends React.Component { 
    constructor(props) { 
     super(props); 
     console.log(props); 
     this.state = { 
      options: props.options, 
      showDropdown: false 
     }; 
    } 
componentWillMount() { 
    var defaultFeatureOptionId = this.props.feature.DefaultFeatureOptionId;  
    var options = [...this.state.options] 
    var isBigButton = false; 
    options.forEach((option) => { 
     if (option.Description.length > 8) { 
      isBigButton = true; 
     } 
    }); 
    options.forEach((option) => { 
     var classes = ""; 
     if (isBigButton) { 
      classes = "option-button big-button hidden"; 
     } else { 
      classes = "option-button small-button hidden"; 
     } 
     if (option.Id === defaultFeatureOptionId) { 
      classes = classes.replace("hidden", " selected"); 
     } 
     option.class = classes; 
    }) 
    this.setState({ options }) 
} 
updateIllustration(value) { 
    console.log(this.props.onClick); 
    this.props.onClick(value); 
} 
toggleDropdown(index) { 
    var options = [...this.state.options]; 
    var option = options[index]; 

    this.updateIllustration(option.Option); 

    var showDropdown = !this.state.showDropdown; 
    this.setState({ 
     showDropdown: showDropdown 
    }) 
    options.forEach((opt) => { 
     opt.class = opt.class.replace("selected", ""); 
     opt.class = opt.class.replace("hidden", ""); 
     if (opt.Id !== option.Id && this.state.showDropdown) { 
      opt.class += " hidden"; 
     } 
     if (opt.Id === option.Id) { 
      opt.class += "selected"; 
     } 
    }); 
    this.setState({ options }) 
} 
render() { 
    if (this.state.options) { 
     return (<div> { 
      this.state.options.map((option, index) => { 
       return <div className={option.class} key={option.Id} onClick={() => this.toggleDropdown(index)}> 
        <div> {option.Description}</div> 
        <img className="option-image" src={option.ImageUrl}></img> 
        <i className={(this.state.showDropdown ? 'hidden' : ' fa fa-chevron-down') } aria-hidden="true" onClick={() => this.toggleDropdown(index)}></i> 
       </div> 
      }) 
     } 

     </div> 
     ) 
    } 
    else { 
     return <div>No options defined</div> 
    } 
} 
} 

module.exports = Button; 

가 하위 구성 요소입니다 :

var ReactDOM = require('react-dom'); 
var React = require('react'); 
var Button = require('./button'); 
var Slider = require('./slider'); 

class Option extends React.Component { 
constructor(props) { 
    super(props); 
} 
updateIllustration(value) { 
    this.props.onClick(value); 
} 
render() {  
    if (this.props.type.Id === 1) { 
     return <div className="option"> <Button options={this.props.options} feature={this.props.feature} onClick={() => this.props.onClick} /></div> 
    } 
    if (this.props.type.Id === 2) { 
     return <div className="option"> <Slider options={this.props.options} feature={this.props.feature} onClick={() => this.props.onClick}/></div> 
    } 
    else { 
     return <div> No option type defined </div> 
    } 
} 
} 

module.exports = Option; 

그리고 여기에 최종 부모 구성 요소입니다

var ReactDOM = require('react-dom'); 
var React = require('react'); 
var ConfigurationService = require('../configurationService'); 
var Option = require('./option'); 

class Feature extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     features: null 
    }; 
    this.getConfiguration(); 

} 
updateIllustration(object) { 
    console.log("MADE IT BACK"); 
    console.log(object); 
} 
getConfiguration() { 
    var self = this; 
    var config = ConfigurationService.getConfiguration('NORMSTAHL', 'SUPERIOR').then(function (config) { 
     console.log("TJE"); 
     console.log(config.data); 
     self.setState({ features: config.data.Features }) 
    });  
} 
render() { 
    if (this.state.features) { 
     return (<div className="feature-component-container"> { 
      this.state.features.map(function (feature) { 
       return <div className="feature" key={feature.Id}> 
        <div className="feature-header">{feature.Description} </div>{ 
         <Option options={feature.FeatureOptions} type={feature.Type} feature={feature} onClick={() => this.updateIllustration } /> 
        }      
       </div> 
      }) 
     } 
     </div>) 
    } 
    else { 
     return <div>no data</div> 
    } 
} 
} 

module.exports = Feature; 

내가 호출 할 함수는 다음

내 손자입니다 updateIllustration 함수이고 지금 당장 나는 어떤 오류도 얻지 못한다. 그러나 그것은 단지 모든 것을 다시 얻지 못할 것이다. console.log ("뒤로 만들다"); 나는 문맥을 가지고 그것을하는 방법에 관해 읽었다. 그러나 모두는 그것이 일한다라고 말한다. 그러나 추천되지 않는다. 그렇다면 권장되는 방법은 무엇입니까?

답변

1

그 이름의 불일치 문제, 부모에서 onClick 이름으로 함수를 전달하므로 자식에서 this.props.updateIllustration 대신 this.props.onClick을 사용해야합니다. updateIllustration은 실제 함수의 이름이며이 함수를 다른 이름으로 전달합니다. 하위 구성 요소에

사용이 :

<Button 
    options={this.props.options} 
    feature={this.props.feature} 
    onClick={() => this.props.onClick()} /> 

업데이트 :

당신은 그 함수를 호출해야합니다. 하위 구성 요소에서

<Option ... onClick={() => this.updateIllustration() } /> //here use() 

: 부모 구성 요소에서

<Button ... onClick={() => this.props.onClick()} /> //here use() 

당신은 당신이 다른 장소를 사용하는 것처럼이 문제가 arrow function을 사용하여 해결하기 위해, map 컨텍스트를 결합하는 것을 잊었다 :

this.state.features.map((feature) => { 
+0

여전히 상위 기능을 사용하지 않습니다. :/ –

+0

이제 "Uncaught TypeError :이 행의 undefined"updateIllustration '속성을 읽을 수 없습니다. : 부모 구성 요소에있는 onClick = {() => this.updateIllustration()} –

+0

은지도의 컨텍스트를 바인딩하는 것을 잊었 기 때문에 'arrow function'을 다음과 같이 사용하십시오 :'this.state.features.map ((feature) => {' –

관련 문제