React onClick işlevi oluşturma sırasında tetikleniyor


212

Bir alt bileşene 2 değer iletiyorum:

  1. Görüntülenecek nesnelerin listesi
  2. silme işlevi.

Nesneler listemi görüntülemek için bir .map () işlevi kullanıyorum (reaksiyon öğretici sayfasında verilen örnekte olduğu gibi), ancak bu bileşendeki düğme onClickoluşturma sırasında işlevi tetikler (oluşturma zamanında tetiklenmemelidir). Kodum şöyle görünüyor:

module.exports = React.createClass({
    render: function(){
        var taskNodes = this.props.todoTasks.map(function(todo){
            return (
                <div>
                    {todo.task}
                    <button type="submit" onClick={this.props.removeTaskFunction(todo)}>Submit</button>
                </div>
            );
        }, this);
        return (
            <div className="todo-task-list">
                {taskNodes}
            </div>
        );
    }
});

Benim sorum: onClickfonksiyon neden render üzerinde ateş ediyor ve nasıl yapmamalı?

Yanıtlar:


528

İşlevi onClick'e geçirmek yerine bu işlevi çağırdığınız için, bu satırı şu şekilde değiştirin:

<button type="submit" onClick={() => { this.props.removeTaskFunction(todo) }}>Submit</button>

=> ES6'da tanıtılan ve React 0.13.3 veya daha üst sürümlerinde desteklenecek Ok İşlevi olarak adlandırılır.


1
bunu coffescript ile nasıl yapabilirim?
vipin8169

14
Bu ok fonksiyonu kıvırcık ayraçlardan da kaçınabilirsiniz. Hangi en iyi uygulamaları maç inanıyorum:onClick={() => this.props.removeTaskFn(todo)}
sospedra

1
Bunu biraz daha açıklar mısınız? İnsanların en iyi uygulama olmadığını söylemeye devam ediyorum ama burada tam olarak ne olduğunu anlamak istiyorum () => Bir ok fonksiyonunun ne olduğunu anlıyorum ama bunun ne olduğunu () ve bunun neden kötü olduğunu anlıyorum?
wuno

@wuno (), anonim işlevinizin parametreleridir. Burada boş çünkü herhangi bir parametre aktarmıyoruz. () İşlevinin () işlevinin () olduğunu düşünün. Şimdi, render () işlevinde neden bağlanma için en iyi uygulama olmadığına ilişkin olarak, her oluşturmada, işlevi çok maliyetli olabilen bileşene yeniden bağlıyoruz.
jaysonder

@LongNguyen Aradığım şey bu! çok teşekkürler
M. Wiśnicki

31

İşlevi çağırmak yerine, değeri işleve bağlayın:

this.props.removeTaskFunction.bind(this, todo)

MDN ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind


2
IMHO ve diğerleri. Clasess veya ciltleme üzerinde vatansız işlevleri tercih etmelisiniz, çünkü bunlar sizi istenmeyen yan etkilere yol açabilir. Bu nedenle, cevapların ikisi de doğru olsa bile, birinin diğerinden daha uygun olduğuna inanıyorum.
sospedra

1
Renderde veya bileşenin başka herhangi bir yerinde doğrudan ciltleme önerilmez. Bağlama her zaman
yapıcıda

15

Özelliğinizin değeri onClickbir işlev çağrısı değil, bir işlev olmalıdır.

<button type="submit" onClick={function(){removeTaskFunction(todo)}}>Submit</button>

8
Render içindeki olay çağrılarında anonim işlevler kullanmayın - başka bir render
işlemini

4

Ok işlevlerini kullanmayan ancak daha basit bir şey olanlar için ... signOut işlevimden sonra parantez eklerken bununla karşılaştım ...

bunu değiştir <a onClick={props.signOut()}>Log Out</a>

bununla <a onClick={props.signOut}>Log Out</a>...! 😆


Aslında bu benim için hiç işe yaramıyor. İşlevi geçtim ve hiçbir zaman parantez eklemedim ve hala render işlemi başlatıldı. Bunun Şubat 19'dan beri değişip değişmediğinden emin değilim ama Long Nguyen ve Vishal Bisht'ın cevabında olduğu gibi bir işlev atamak sorunu çözdü.
BitShift

4

JSX, HTML'ye çok benzer olduğu için ReactJS ile birlikte kullanılır ve programcılara HTML kullanma hissi verirken sonuçta bir javascript dosyasına aktarılır.

Bir for döngüsü yazmak ve işlevi {this.props.removeTaskFunction (todo)} olarak belirtmek, döngü her tetiklendiğinde işlevleri yürütür.

Bu davranışı durdurmak için işlevi onClick'e döndürmemiz gerekir.

Yağ ok işlevi, bind özelliğiyle birlikte gizli bir dönüş deyimine sahiptir . Böylece Javascript de fonksiyonları döndürebilir gibi işlevi OnClick için döndürür !!!!!

Kullan -

onClick={() => { this.props.removeTaskFunction(todo) }}

bunun anlamı-

var onClick = function() {
  return this.props.removeTaskFunction(todo);
}.bind(this);

1

JSX, süslü parantez içindeki JavaScript ifadelerini değerlendirecek

Bu durumda, this.props.removeTaskFunction(todo)çağrılır ve dönüş değerionClick

Sağlamanız gereken onClickbir işlevdir. Bunu yapmak için, değeri anonim bir işlevde sarabilirsiniz.

export const samepleComponent = ({todoTasks, removeTaskFunction}) => {
    const taskNodes = todoTasks.map(todo => (
                <div>
                    {todo.task}
                    <button type="submit" onClick={() => removeTaskFunction(todo)}>Submit</button>
                </div>
            );
    return (
        <div className="todo-task-list">
            {taskNodes}
        </div>
        );
    }
});

1

Benzer bir sorun vardı, kodum:

function RadioInput(props) {
    return (
    <div className="form-check form-check-inline">
        <input className="form-check-input" type="radio" name="inlineRadioOptions" id={props.id} onClick={props.onClick} value={props.label}></input>
        <label className="form-check-label" htmlFor={props.id}>{props.label}</label>
    </div>
    );
  }
class ScheduleType extends React.Component
{
    renderRadioInput(id,label)
    {
        id = "inlineRadio"+id;
        return(
            <RadioInput
                id = {id}
                label = {label}
                onClick = {this.props.onClick}
            />
        );

    }

Nerede olmalı

onClick = {() => this.props.onClick()}

içinde RenderRadioInput

Benim için sorunu düzeltti.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.