Реагировать: вернуть дочерний новый вставленный элемент родительскому для обновления состояния

#javascript #reactjs #meteor #state

#javascript #reactjs #метеор #состояние

Вопрос:

У меня есть родительский компонент в React, который отображает список элементов, а также состояние (selectedList), которое присваивает активный класс этому элементу списка отображает другие компоненты в зависимости от активного класса. Это родительский компонент.

В дочернем я отображаю форму, в которой я могу задать новый список и событие onSubmit, в котором я вставляю его в коллекцию (meteor mongo)

Проблема в том, что я не могу установить связь между новым элементом (id) и родительским компонентом, потому что я хотел бы выбрать вновь созданный список (поэтому укажите активный класс и отобразите другие компоненты).). Тогда я думаю, что мне следует обновить state.selectedListId но я не знаю, как в дочернем элементе я могу отправить его родительскому компоненту?

Вот несколько строк кодов:

РОДИТЕЛЬСКИЙ ЭЛЕМЕНТ (СТРАНИЦА)

 class TodosPage extends Component {

constructor(props) {
    super(props);
    this.state = {
        listSelected: "",
    };
}

selectList(listId) {
    this.setState({ listSelected: listId });
}

renderLists() {
    return this.props.lists.map((list) => (
        <List 
            selectedItemId={this.state.listSelected}
            selectList={() => this.selectList(list._id)}
            key={list._id}
            list={list}
            countPendingTasks={this.countPendingTasks(list._id)}
        />
    ));
}

render() {
    return (
        <div className="container">
                <ListForm />
                <ListGroup>
                    {this.renderLists()}
                </ListGroup>
  

ДОЧЕРНИЙ ЭЛЕМЕНТ (форма списка)

 handleSubmit(event) {
    event.preventDefault();

    const name = ReactDOM.findDOMNode(this.refs.nameInput).value.trim();
    Meteor.call('lists.insert', name, (err, listId) => {
        console.log("in method insert = "   listId);
        // HERE I CAN HAVE THE GOOD ID
    });
    ReactDOM.findDOMNode(this.refs.nameInput).value = '';
}

render() {
    return (
        <Form bsClass="col-xs-12" onSubmit={this.handleSubmit.bind(this)} >
            <FormGroup bsClass="form-group">
                <FormControl type="text" ref="nameInput" placeholder="Add New List" />
            </FormGroup>
        </Form>
    );
}
  

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

Спасибо за помощь

Ответ №1:

Попросите родителя ( TodosPage ) передать функцию в качестве реквизита своему дочернему элементу ( ListForm ). Затем onSubmit , ListForm вызовите функцию.

 class TodosPage extends React.Component {
  handleListFormSubmit = (goodId) => {
    // do something with goodId
  }
  render() {
    return <ListForm onSubmit={this.handleListFormSubmit} />;
  }
}

class ListForm extends React.Component {
  handleSubmit = (event) => {
    // get GOOD ID from the form, then call the parent function
    // [...]
    this.props.onSubmit(goodId);
  }
  render() {
    <Form onSubmit={this.handleSubmit}>
      {/* form stuff here */}
    </Form>
  }
}
  

Комментарии:

1. Эй, спасибо за ответ, но я не могу установить состояние в родительском элементе, я тоже мог бы это сделать, но у меня ошибка: исключение при доставке результата вызова ‘lists.insert’: TypeError: this.SelectList не является функцией.. Если я сделаю в родительском handleListFormSubmit = (GoodID) => { this.setState(listSelected: GoodID); } .. У вас есть идея?

Ответ №2:

На самом деле, это было довольно просто,

Я просто использовал свою функцию SelectList и, как сказал @Ty Le, отправил ее дочернему элементу через prop, но чтобы установить новое состояние, я должен добавить в свой родительский конструктор:

 this.selectList = this.selectList.bind(this);
  

Или я получаю сообщение об ошибке: this.setState не определено..

Спасибо

Комментарии:

1. Правильно, вам нужно bind(this) , если вы используете обычные функции, как в selectList(listId) {} . Если вы используете функции со стрелками ( selectList = (listId) => {} ), я не думаю, что вам нужно это привязывать.