Soru React formu onChange-> setState bir adım geride


Bu problemi bir webapp ile karşılaştım ve bunu kopyaladım. jsfiddle. Aslında, aramak için bir giriş istiyorum this.setState({message: input_val}) Bir şey yazdığım her zaman, daha sonra iletiyi Message sınıfına yeniden veren üst App sınıfına iletir. Ancak çıktı aslında her zaman yazdığımın arkasında bir adım gibi görünüyor. Jsfiddle demo kendini açıklayıcı olmalıdır. Bunu sormak için yanlış bir şey yapıp yapmadığımı merak ediyorum.

html

<script src="http://facebook.github.io/react/js/jsfiddle-integration.js"></script>
<div id='app'></div>

js

var App = React.createClass({
    getInitialState: function() {
        return {message: ''}
    },
    appHandleSubmit: function(state) {
        this.setState({message: state.message});
        console.log(this.state.message);
    },
    render: function() {
        return (
            <div className='myApp'>
            <MyForm onChange={this.appHandleSubmit}/>
            <Message message={this.state.message}/>
            </div>
        );
    }
});

var MyForm = React.createClass({
    handleSubmit: function() {
        this.props.onChange(this.state);
    },
    handleChange: function(e) {
        console.log(e.target.value);
        this.setState({message: e.target.value});
        this.handleSubmit();
    },
    render: function() {
        return (
            <form className="reactForm" onChange={this.handleChange}>
            <input type='text' />
            </form>
        );
    }
});

var Message = React.createClass({
    render: function() {
        return (
            <div className="message">
                <p>{this.props.message}</p>
            </div>
        )
    }
});

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

25
2018-02-27 20:38


Menşei




Cevaplar:


Bir çağrı setState senkronize değil "Beklemede durum geçişi" oluşturur. (Görmek İşte daha fazla ayrıntı için). Açıkça yeni geçmelisin input yükseltilen etkinliğin bir parçası olarak değer handleSubmit örneğinizde).

Görmek bu örnek.

handleSubmit: function(txt) {
    this.props.onChange(txt);
},
handleChange: function(e) {
    var value = e.target.value;
    this.setState({message: value});
    this.handleSubmit(value);
},

31
2018-02-27 20:54



Siz 41K ününüzü hak ediyorsunuz! - Andrew Duffy


Bunu yapmanın daha basit bir yolu var. setState(updater, callback) bir uyumsuzluk işlevidir ve ikinci argüman olarak geri bildirimi alır,

Sadece geçmek handleSubmit bir geri arama olarak setState yöntem, setState sonra sadece bu şekilde tamamlandı handleSubmit infaz edilecek.

Örneğin için.

handleChange: function(e) {
    console.log(e.target.value);
    this.setState({message: e.target.value}, this.handleSubmit);
}

Yukarıdaki gibi handleChange () yöntemini değiştirmeyi deneyin ve işe yarayacaktır.

kullanma sözdizimi için setState şuna göz at bağlantı


17
2017-09-28 19:38



+1 Bu, düşündüğüm en mantıklı cevap. Alternatifi componentDidUpdate ile de söyleyebilirdiniz;) - Kjellski


MyForm'un burada eyalet kullanması için bir sebep yok. Ayrıca onChange'ı ilgilendiğiniz giriş yerine forma koymak tuhaftır. Kontrollü bileşenler tercih edilmeli çünkü davranışları daha açık ve herhangi bir zamanda Uygulamanın mesaj durumu değişiyor (örneğin, iletinin daha sonra değiştirmesine izin verseniz bile), her yerde doğru olacaktır.

Bu ayrıca kodunuzu biraz daha kısa ve önemli ölçüde daha basit hale getirir.

var App = React.createClass({
    getInitialState: function() {
        return {message: ''}
    },
    appHandleSubmit: function(message) {
        this.setState({message: message});
    },
    render: function() {
        return (
            <div className='myApp'>
                <MyForm onChange={this.appHandleSubmit} 
                        message={this.state.message} />
                <Message message={this.state.message}/>
            </div>
        );
    }
});

var MyForm = React.createClass({
    handleInputChange: function(e){
        this.props.onChange(e.target.value);
    },
    // now always in sync with the parent's state
    render: function() {
        return (
            <form className="reactForm">
                <input type='text' onChange={this.handleInputChange}
                       value={this.props.message} />
            </form>
        );
    }
});

jsbin


4
2018-02-27 21:22



Refakatçı için teşekkürler, kodunuzu okudum ve ondan iyi puanlar aldım. This.props kullanmak gibi saf görünümler için iyi bir fikir gibi görünüyor ve this.state kullanarak kontrolörler için iyidir. - Keith Yong
Çoğunlukla evet. Bazen açık / kapalı durumun bileşene özel olarak saklanabileceği bir açılır kapanma gibi bir şey var (neden açılırsa ebeveynin açılıp açılmamasını umursasın ki?). Ayrıca bazen UI bileşenleri imleç pozisyonu gibi bir şeyi takip etmeli ve bunu render halinde kullanmalıdır, böylece kendi yerel durumlarında biter. - FakeRainBrigand
FYI - bu kod olduğu gibi çalışmıyor. onChange giriş kutusunun asıl metnini orada yaptığınız gibi bir değer aktarmaz (a SyntheticEvent aslında geçti). Ayrıca bir kapsayıcının, bir çocuk bileşeninin nasıl işlendiğine dair bir şey bilmesi gerekmeyeceğini, bu yüzden kullanılmaması gerektiğini umuyorum. e.target.valueörneğin, giriş kutusundan değeri ayıklamak için. Bu nedenle, dolaylı bir seviyeye sahip olmak, MyForm orijinal kodda. - WiredPrairie
Teşekkürler, sabit ve demo ekledi. - FakeRainBrigand


Bir bileşenin durumuna biraz değer katmak için 3 işleyici işlevini tanımlamam için çok hantal buldum, bu yüzden hiç bir eyalet kullanmamaya karar verdim. Az önce istenen değeri depolayan bileşene ek bir özellik tanımladım.

Bu yüzden böyle bir şeye benzeyen bir kodla karşılaştım:

//...
},
text: '',
handleChange: function(event) {
  this.text = event.target.value;
  this.forceUpdate();
},
render: function() {
    return <div>
      <InputComponent onChange={this.handleChange}/>
      <DisplayComponent textToDisplay={this.text}/>
      </div>
}
//...

0
2018-04-15 21:42