2016-05-20 2 views
7

Я действительно новичок в реактиве, и я вытягиваю свои волосы, пытаясь решить то, что кажется мне простой проблемой. Вот изображение компонента, который я построил.Реагирование от ребенка к родителям в реакторе (JSX) без потока

Color Picking Component

То, что я пытаюсь выполнить кажется тривиальным, но буквально в каждой статье я прочитал объяснить, что делать сказал мне что-то другое, а не один из решений работал. Это нарушает это: когда пользователь нажимает на тег, он создает лоток и перебирает массив цветов для создания цветных кнопок. При нажатии кнопки цвета необходимо передать цвет, который был нажат на его родительский компонент, и запустить функцию для обновления цвета. Я читал о флюсе, пузырях событий, привязывая «это» к свойству, и ни одно из этих решений, похоже, не срабатывало. Документы React в основном бесполезны для новичков, подобных мне. Я хочу избежать сложных структур событий, таких как поток в этот момент, поскольку я добавляю некоторые простые компоненты в существующее приложение, которое я не писал в React изначально.

Кроме того, PS, этот код в JSX, который имеет для меня гораздо больше смысла, чем прямой JS. Заранее спасибо за вашу помощь!

var colorsArray = ["#ED5851", "#9CCC64", "#337AEC", "#ff7a45", "#7E58C2", "#FFEB3B", "#78909C", "#FFFFFF", "#213a4b"]; 

var EditDrawer = React.createClass({ 
    updateColor: function() { 
     console.log("New Color: " + i); 
    }, 
    render: function(){ 
     var passTarget = this; 
     return (
      <div className="container-fluid animated fadeIn extra-fast-animation tag-edit-drawer"> 
       <div className="row"> 
        <div className="col-xs-12"> 
         {colorsArray.map(function(object, i){ 
          return <ColorButton buttonColor={object} key={i} />; 
         })} 
        </div> 
       </div> 
      </div> 
     ); 
    } 
}) 

var ColorButton = React.createClass({ 
    render: function(){ 
     var buttonStyle = { 
      backgroundColor: this.props.buttonColor, 
     }; 
     return (
      <div className="tag-edit-color-button" style={buttonStyle} > 
      </div> 
     ) 
    } 
}) 
+1

Как примечание , вот два метода, которые я пытался использовать, но ни один из них не работал. http://haochuan.io/how-to-communicate-between-pure-react-components-without-flux/ http://andrewhfarmer.com/component-communication/#3-callback-functions –

ответ

6

Функция обратного вызова должна работать. Как вы упомянули в своем предыдущем комментарии вы можете использовать захваченный this для доступа к функции updateColor от ребенка:

var passTarget = this; 
... 
... 
return <ColorButton 
    buttonColor={object} 
    key={i} 
    update={passTarget.updateColor} /> 

Или как упомянуто Bogdan вы можете передать его через карту после того, как функции обратного вызова:

{colorsArray.map(function(object, i){ 
    return <ColorButton 
      buttonColor={object} 
      key={i} 
      update={this.updateColor} />; 
}, this)} 

Ваш <ColorButton /> компонент должен затем быть в состоянии выполнить простую функцию OnClick:

onClick={this.props.update} 

И то вы можете просто использовать обычные цели событий в родительском компоненте, чтобы захватить цвет кнопки, которая была нажата:

updateColor: function(e) { 
    console.log(e.target.style.backgroundColor); 
} 

Вот полный DEMO продемонстрировать.

+0

Это выглядит действительно многообещающим. Я оставил работу на выходные, но я буду проверять ее на следующей неделе и обновить ее здесь. Спасибо за вашу помощь! –

+0

Это сработало красиво, спасибо за помощь! –

3

Вы можете просто передать функцию обратного вызова в ребенка из родительского компонента, так просто, как это:

<ColorButton buttonColor={object} key={i} onColorSelect={this.updateColor}/> 

(при использовании React.createClass все методы класса уже связаны с this, так что вы не требуется звонить .bind(this)).

Затем из ColorButton компонента вы можете назвать этот обратный вызов как this.props.onColorSelect(...).

JS Bin пример: http://jsbin.com/fivesorume/edit?js,output

+0

Спасибо Bogdan ! К сожалению, это просто возвращает ошибку: «Невозможно прочитать свойство« updateColor »неопределенного». Я думаю, это потому, что я перебираю массив, и поэтому «это» переопределяется. Чтобы обойти это, я ранее определил переменную, чтобы захватить «это», и это позволяет мне получить доступ к функции updateColor от дочернего элемента. Единственная проблема в том, что если я попытаюсь передать что-либо функции, она будет запускать функцию девять раз при создании, а не ждать щелчка. 'onClick = {this.props.onColorSelect (this.props.buttonColor)}' [выводит это] (http://imgur.com/hTFcUN3) –

+0

о передаче 'this' в Array.map - вы также можете пройти это как второй аргумент '.map (function ..., this)', то это из внешней области будет использоваться. О 'onClick = {this.props.onColorSelect (this.props.buttonColor)}', вы не передаете функцию здесь - вы вызываете ее во время рендеринга и передачи результата. Вам нужно создать отдельную функцию в вашем компоненте. –

+0

Это имеет большой смысл. Я попробую на следующей неделе. Спасибо за вашу помощь! –

1

OK, это довольно просто в Реагировать без использования flux или redux, подобных проходя вниз реквизит от родителей к ребенку, здесь мы можем использовать функцию обратного вызова, как это:

var colorsArray = ["#ED5851", "#9CCC64", "#337AEC", "#ff7a45", "#7E58C2", "#FFEB3B", "#78909C", "#FFFFFF", "#213a4b"]; 


var EditDrawer = React.createClass({ 
    updateColor: function(i) { 
     alert("New Color: " + i); 
    }, 
    render: function(){ 
     return (
      <div className="container-fluid animated fadeIn extra-fast-animation tag-edit-drawer"> 
       <div className="row"> 
        <div className="col-xs-12"> 
         {colorsArray.map(function(object, i){ 
          return <ColorButton buttonColor={object} key={i} updateColor={this.updateColor}/>; 
         }, this)} 
        </div> 
       </div> 
      </div> 
     ); 
    } 
}); 


var ColorButton = React.createClass({ 
    updateColor: function() { 
     this.props.updateColor(this.props.buttonColor); 
    }, 
    render: function(){ 
     var buttonStyle = { 
      backgroundColor: this.props.buttonColor, 
     }; 
     return (
      <div className="tag-edit-color-button" 
      style={buttonStyle} 
      onClick={this.updateColor}> 
       this.props.buttonColor 
      </div> 
     ) 
    } 
}); 
Смежные вопросы