React.js отправляет дочернее состояние обратно родительскому [duplicate]

быстрый и грязный один вкладыш:

'-'.join(str(x) for x in list(tuple(datetime.datetime.now().timetuple())[:6]))

'2013-5-5-1-9-43'

227
задан KendallB 1 August 2015 в 15:07
поделиться

6 ответов

213
ответ дан Community 25 August 2018 в 08:27
поделиться

В основном вы используете реквизиты для отправки информации от ребенка и родителя.

Добавляя все замечательные ответы, позвольте мне привести простой пример, объясняющий передачу значений от дочернего к родительскому компоненту в React

App.js

class App extends React.Component {
      constructor(){
            super();
            this.handleFilterUpdate = this.handleFilterUpdate.bind(this);
            this.state={name:'igi'}
      }
      handleFilterUpdate(filterValue) {
            this.setState({
                  name: filterValue
            });
      }
   render() {
      return (
        <div>
            <Header change={this.handleFilterUpdate} name={this.state.name} />
            <p>{this.state.name}</p>
        </div>
      );
   }
}

Header.js

class Header extends React.Component {
      constructor(){
            super();
            this.state={
                  names: 'jessy'
            }
      }
      Change(event) {

      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

   render() {
      return (
       <button onClick={this.Change.bind(this)}>click</button>

      );
   }
}

Main.js

import React from 'react';
import ReactDOM from 'react-dom';

import App from './App.jsx';

ReactDOM.render(<App />, document.getElementById('app'));

То есть, теперь вы можете передавать значения с вашего клиента на сервер.

Take посмотрите на функцию «Изменить» в Header.js

Change(event) {
      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

. Так вы вставляете значения в реквизиты с клиента на сервер

5
ответ дан Ignatius Andrew 25 August 2018 в 08:27
поделиться

Вот простая трехэтапная реализация ES6 с использованием привязки функций в родительском конструкторе. Это первый способ, рекомендуемый официальным учебным пособием (существует также синтаксис полей открытых классов, который здесь не рассматривается). Вы можете найти всю эту информацию здесь https://reactjs.org/docs/handling-events.html

Связывание родительских функций, чтобы дети могли звонить им (и передавать данные вверх для родителя!: D)

  1. Убедитесь, что в родительском конструкторе вы связываете функцию, созданную вами в родительском
  2. . Передайте связанную функцию вниз ребенку в качестве опоры (Нет lambda, потому что мы передаем функцию ref)
  3. Вызов связанной функции из дочернего события (Lambda! Мы вызываем функцию при запуске события. Если мы этого не сделаем, функция будет автоматически запускаться при загрузке и не запускаться в событии.)

Родительская функция

handleFilterApply(filterVals){} 

Родительский конструктор

this.handleFilterApply = this.handleFilterApply.bind(this);

Prop Passed to Child

onApplyClick = {this.handleFilterApply}

Ребенок [Call]

onClick = {() => {props.onApplyClick(filterVals)}
1
ответ дан Jordan H 25 August 2018 в 08:27
поделиться

Кажется, есть простой ответ. Рассмотрим это:

var Child = React.createClass({
  render: function() {
    <a onClick={this.props.onClick.bind(null, this)}>Click me</a>
  }
});

var Parent = React.createClass({
  onClick: function(component, event) {
    component.props // #=> {Object...}
  },
  render: function() {
    <Child onClick={this.onClick} />
  }
});

Ключ вызывает bind(null, this) в событии this.props.onClick, переданном из родителя. Теперь функция onClick принимает аргументы component, AND event. Я думаю, что это лучший из всех миров.

UPDATE: 9/1/2015

Это была плохая идея: позволить деталям реализации ребенка утечка в родительский элемент никогда не был хорошим путем , См. Ответ Себастьяна Лорбера.

24
ответ дан KendallB 25 August 2018 в 08:27
поделиться

Вопрос заключается в том, как передать аргумент от дочернего к родительскому компоненту. Этот пример прост в использовании и проверен:

//Child component
class Child extends React.Component {
    render() {
        var handleToUpdate  =   this.props.handleToUpdate;
        return (<div><button onClick={() => handleToUpdate('someVar')}>Push me</button></div>
        )
    }
}

//Parent component
class Parent extends React.Component {
        constructor(props) {
        super(props);
        var handleToUpdate  = this.handleToUpdate.bind(this);
    }

        handleToUpdate(someArg){
            alert('We pass argument from Child to Parent: \n' + someArg);
    }

    render() {
        var handleToUpdate  =   this.handleToUpdate;
        return (<div>
                    <Child handleToUpdate = {handleToUpdate.bind(this)} /></div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <Parent />,
        document.querySelector("#demo")
    );
}

Посмотрите на JSFIDDLE

6
ответ дан Roman 25 August 2018 в 08:27
поделиться

Обновление (9/1/15): ОП задал этот вопрос немного движущейся мишенью. Он был обновлен снова. Итак, я чувствую ответственность за обновление своего ответа.

Во-первых, ответ на ваш предоставленный пример:

Да, это возможно.

Вы можете решить эту проблему, обновив Child onClick как this.props.onClick.bind(null, this):

var Child = React.createClass({
  render: function () {
    return <a onClick={this.props.onClick.bind(null, this)}>Click me</a>;
  }
});

Обработчик событий в вашем родителе может затем получить доступ к компоненту и событию следующим образом:

  onClick: function (component, event) {
    // console.log(component, event);
  },

Снимок JSBin

Но сам вопрос вводит в заблуждение

Родитель уже знает Child props.

Это не ясно в приведенном примере, потому что на самом деле никаких реквизитов не предоставляется. Этот примерный код может лучше поддерживать задаваемый вопрос:

var Child = React.createClass({
  render: function () {
    return <a onClick={this.props.onClick}> {this.props.text} </a>;
  }
});

var Parent = React.createClass({
  getInitialState: function () {
    return { text: "Click here" };
  },
  onClick: function (event) {
    // event.component.props ?why is this not available? 
  },
  render: function() {
    return <Child onClick={this.onClick} text={this.state.text} />;
  }
});

В этом примере становится намного понятнее, что вы уже знаете, каковы реквизиты Ребенка.

JSBin snapshot

Если это действительно касается реквизита ребенка ...

Если это действительно касается реквизита ребенка, вы можете избежать любого подключения с помощью Ребенок вообще.

JSX имеет атрибуты распространения] , которые я часто использую на таких компонентах, как Child. Он принимает все props и применяет их к компоненту. Ребенок будет выглядеть так:

var Child = React.createClass({
  render: function () {
    return <a {...this.props}> {this.props.text} </a>;
  }
});

Позволяет использовать значения непосредственно в родительском объекте:

var Parent = React.createClass({
  getInitialState: function () {
    return { text: "Click here" };
  },
  onClick: function (text) {
    alert(text);
  },
  render: function() {
    return <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />;
  }
});

Снимок JSBin

Нет необходимости в дополнительной настройке при подключении дополнительных дочерних компонентов

var Parent = React.createClass({
  getInitialState: function () {
    return {
      text: "Click here",
      text2: "No, Click here",
    };
  },
  onClick: function (text) {
    alert(text);
  },
  render: function() {
    return <div>
      <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />
      <Child onClick={this.onClick.bind(null, this.state.text2)} text={this.state.text2} />
    </div>;
  }
});

JSBin snapshot

Но я подозреваю, что это не ваш фактический прецедент , Итак, давайте копаем дальше ...

Надежный практический пример

Общий характер представленного примера трудно обсуждать. Я создал компонент, который демонстрирует практическое применение для вышеупомянутого вопроса, реализованного в способе Reacty :

Рабочий пример DTServiceCalculator DTServiceCalculator repo

Этот компонент является простым калькулятором обслуживания. Вы предоставляете ему список услуг (с именами и ценами), и он рассчитает общее количество выбранных цен.

Дети блаженны не знают

ServiceItem является дочерним компонентом в этом примере. У него мало мнений о внешнем мире. Это требует нескольких реквизитов , одна из которых является функцией, которая будет вызываться при нажатии.

<div onClick={this.props.handleClick.bind(this.props.index)} />

Он ничего не делает, кроме как позвонить предоставленному handleClick с предоставленным index [ источником ].

Родители - Дети

DTServicesCalculator - это parent-component - это пример. Это тоже ребенок. Давайте посмотрим.

DTServiceCalculator создает список дочерних компонентов (ServiceItem s) и предоставляет им реквизит [ source ]. Это родительский компонент ServiceItem, но это дочерний компонент компонента, передающий ему список. Он не владеет данными. Поэтому он снова делегирует обработку компонента его исходному компоненту source

<ServiceItem chosen={chosen} index={i} key={id} price={price} name={name} onSelect={this.props.handleServiceItem} />

handleServiceItem захватывает индекс, переданный от дочернего элемента, и предоставляет его своему родительскому источнику [ ]

handleServiceClick (index) {
  this.props.onSelect(index);
}

Владельцы знают все

Концепция «Собственность» является важной в Реактировании. Я рекомендую прочитать больше об этом здесь .

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

Когда мы, наконец, доберемся туда, мы обрабатываем выбор / отключение состояния следующим образом [ source ]:

handleSelect (index) {
  let services = […this.state.services];
  services[index].chosen = (services[index].chosen) ? false : true;
  this.setState({ services: services });
}

Заключение

Постарайтесь, чтобы ваши внешние компоненты были максимально непрозрачными. Стремитесь убедиться, что у них очень мало предпочтений о том, как родительский компонент может их реализовать.

Имейте в виду, кто владеет данными, которыми вы управляете. В большинстве случаев вам необходимо делегировать обработку событий по дереву компоненту, который владеет , который находится в состоянии.

Кроме того: Тип потока - хороший способ уменьшить этот тип необходимых подключений в приложениях.

139
ответ дан Vikas Yadav 25 August 2018 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: