2017-02-07 3 views
0

У меня есть компонент response.js, где я хочу передать кучу разных методов дочерним компонентам из родительского компонента, методы изменят состояние родительского компонента.Передача нескольких методов в пределах одной пропитки React.js

class Page extends Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     items: this.props.items, 
     currentItemID: 1 
    }; 

    this.actions = this.actions.bind(this); 
    } 

    render() { 
    return (
     <div className="page"> 
     { 
      this.state.items.map(item => 
      <Item key={item._id} item={item} actions={this.actions} /> 
     ) 
     } 
     </div> 
    ); 
    } 

    actions() { 
    return { 
     insertItem: function (itemID) { 
     const currentItems = this.state.items; 
     const itemPosition = this.state.items.map((item) => item._id).indexOf(itemID); 

     const blankItem = { 
      _id: (new Date().getTime()), 
      content: '' 
     }; 

     currentItems.splice(itemPosition + 1, 0, blankItem) 

     this.setState({ 
      items: currentItems, 
      lastAddedItemID: blankItem._id 
     }); 
     }, 
     setCurrentItem: function (itemID) { 
     this.setState({ currentItemID: itemID }); 
     }, 
     focus: function(itemID) { 
     return (itemID === this.state.currentItemID); 
     } 
    } 
    } 

В моем детском компоненте, я пытаюсь использовать метод фокусировки в методе componentDidMount lifecyle, как показано ниже:

componentDidMount() { 
    if (this.props.actions().focus(this.props.item._id)) { 
     this.nameInput.focus(); 
    } 
    } 

Однако я получаю ошибку

Uncaught TypeError: Cannot read property 'currentItemID' of undefined

в определении метода фокусировки, в рамках методов действий. Может ли кто-нибудь указать мне в правильном направлении, почему я получаю ошибку или альтернативный способ передать несколько действий дочерним компонентам?

+0

Я думаю, ваша основная ошибка - то, что вы называете своими действиями внутри метода - это создаст некоторые неожиданные проблемы, попытайтесь передать объект дочернему элементу, а не функции, и если вы используете es5 - свяжите 'this' внутри каждая функция (ее основная ошибка) –

+0

Можете ли вы привести мне пример того, как связать одну из функций с «этим», пожалуйста? – Hirvesh

+0

.bind (this) - как в ответе ниже –

ответ

5

контекст не передается функции, тогда функция «this» в функции принадлежит самой функции, а не компоненту. Вы можете решить ее таким образом (поместите функции в компоненты):

 actions() { 
     return { 
      insertItem: this.insertItem.bind(this), 
      setCurrentItem: this.setCurrentItem.bind(this), 
      focus: this.focus.bind(this), 
     } 
     } 
     insertItem(itemID) { 
     const currentItems = this.state.items; 
     const itemPosition = this.state.items.map((item) => item._id).indexOf(itemID); 

     const blankItem = { 
      _id: (new Date().getTime()), 
      content: '' 
     }; 

     currentItems.splice(itemPosition + 1, 0, blankItem) 

     this.setState({ 
      items: currentItems, 
      lastAddedItemID: blankItem._id 
     }); 
     }, 
     setCurrentItem(itemID) { 
     this.setState({ currentItemID: itemID }); 
     }, 
     focus(itemID) { 
     return (itemID === this.state.currentItemID); 
     } 

, но тем не менее, порекомендован способ поставить функции в компонентах, как и выше, и удалите метод действия и сделать это:

<Item key={item._id} item={item} actions={{ 
      insertItem: this.insertItem.bind(this), 
      setCurrentItem: this.setCurrentItem.bind(this), 
      focus: this.focus.bind(this) 
     }} /> 

или

<Item key={item._id} item={item} actions={{ 
      insertItem:() => this.insertItem(), 
      setCurrentItem:() => this.setCurrentItem(), 
      focus:() => this.focus() 
     }} /> 
+0

На самом деле компонент компонента рекурсивный, в нем есть другие вложенные элементы, то как мне передать различные методы вложенному элементу в моем компоненте элемента? Это немного озадачило меня. – Hirvesh

+0

@the_archer в дочернем компоненте, если вы хотите вызвать дочерний дочерний элемент (дочерний элемент child), выполните следующие действия: или вы можете даже передать все (действия и другие вещи в реквизитах) следующим образом: challenger

+0

спасибо! понял :) – Hirvesh