2016-03-04 2 views
0

У меня есть приложение с 3 компонентами. Первый App.jsx , который вызывает компонент ToDoList следующим образом:reactjs изменить состояние ребенка от родителя

<TodoList items={this.state.items} loaded={this.state.loaded} /> 

ToDoList компонент делает несколько компонентов TodoListItem

module.exports = React.createClass({ 
render: function(){ 
    return (
    <ul> 
    {this.renderList()} 
    </ul> 
) 
}, 
renderList: function(){ 
    var children = []; 
    for(var key in this.props.items) { 
     if(this.props.items[key].text){ 
     var listItem = this.props.items[key]; 
     listItem.key = key; 
     children.push(
      <TodoListItem item={listItem} key={key} onEdit={this.handleItemEdit} /> 
     ) 
     } 
    } 
    return children; 
}, 
handleItemEdit: function(component){ 
    console.log(component); 
} 
}); 

Тогда в моей TodolistItem компонент им рендеринга нескольких элементов Li

module.exports = React.createClass({ 
getInitialState: function(){ 
    return { 
    text: this.props.item.text, 
    done: this.props.item.done 
    } 
}, 
render: function(){ 
    return (
    <li onClick="this.props.onEdit.bind(null,this)">{this.state.text}</li> 
) 
}, 

}); 

Когда я нажимаю на li, функция handlItemEdit в функции родительского элемента запускается, вопрос в том, как я могу изменить текстовое значение дочернего элемента в его handleItemEdit функции родителя? Что им пытается сделать, когда вы нажимаете на литии открыть загрузочную модальность с полем ввода, изменить его текст, сохранить и передать новый реквизит TodoListItem

ответ

0

В TodoList компоненты вы должны написать getInitialState и сохранить предметы из реквизита в состояние, то в визуализации элементов переходить из состояния (не из реквизита, как вы делали) к TodoListItem компоненту:

for(var key in this.state.items) { 
    if(this.state.items[key].text){ 
    var listItem = this.state.items[key]; 
    listItem.key = key; 
    children.push(
     <TodoListItem item={listItem} key={key} onEdit={this.handleItemEdit} /> 
    ) 
    } 
} 

Если вы звоните setState в handleItemEdit методы render() будет видеть обновленное состояние и будет выполняться. В этом случае все, что вам нужно сделать, это изменение состояние в вашем handleItemEdit и это будет передано в TodolistItem, где вы должны использовать props, не state в визуализации, например:

render: function(){ 
    return (
    <li onClick="this.props.onEdit.bind(null,this.props)">{this.props.text}</li> 
) 
}, 

Уведомления вы проходящий реквизит onEdit, так что вы должны Чейн handleItemEdit так:

handleItemEdit: function(itemProps){ 
    console.log('You clicked: ' + this.props.items[itemProps.key]); 
} 
+0

Большое спасибо за ваш ответ! Поскольку реквизит в todoList исходит из запроса http, я добавил componentWillReceiveProps: function() { this.setState ({items: this.props.items}); } Теперь в handleItemEdit, как я могу только изменить значение щелкнутого li? Могу ли я сделать это по его ключу? –

+0

'handleItemEdit' должен быть фактически в компоненте TodolistItem не в компоненте TodoList ... это решит вашу проблему –

+0

, вы также можете прочитать эту статью [https://facebook.github.io/react/tips/communicate-between- components.html), чтобы описать, как обрабатывать связь, составлять компоненты, чтобы решить вашу проблему по-другому (как вы хотели или хотели) –

0

Я проверил решение вашей проблемы в ECMAScript 6 синтаксиса. Было бы очень просто использовать это решение в ваших обозначениях. В основном, вам нужно передать от родителя к дочернему, а затем использовать его, когда вы привязываете событие onClick к родительскому (так что вы можете иметь в функции обработчика события) в качестве второго параметра вы передаете props ребенка, где key prop будет указывать на очень зачеркнутый элемент. Тогда очень просто закодировать состояние родителя, это приведет к рендерингу родителя и каскаду для рендеринга дочернего элемента с новым (измененным пользователем) реквизитом.

TodoList.js

class TodoList extends Component { 
    render(){ 
     return (
      <ul> 
       {this.props.items.map(function(listItem, key) { 
        return (listItem.text && 
         <TodoListItem item={listItem} todoList={this} key={key} onEdit={this.handleItemEdit}/> 
        ); 
       })} 
      </ul> 
     ) 
    }; 

    handleItemEdit(itemProps){ 
     console.log('You clicked: ' + this.props.items[itemProps.key].text); 
    }; 
} 

export default TodoList; 

TodoListItem.js

import React, { Component } from 'react'; 

class TodoListItem extends Component { 
    render() { 
     return (
      <li onClick={this.props.onEdit.bind(this.props.todoList, this.props.item)}>{this.props.item.text}</li> 
     ) 
    } 
} 

export default TodoListItem; 

Я проверил его и печатает сам текст вы нажали на консоли. Это означает, что oyu имеет доступ к этому объекту TodoListItem, и вы можете изменить его состояние в компоненте TodoList.

Смежные вопросы