React

2017-06-10 82 views
6

içinde durumu güncelleştirmek için zarif ES6 yolu React'ta state güncelleştirmesinin sözdizimi çok değişti. Onu başlatmak ve güncellemek için en basit ve zarif yolu bulmaya çalışıyorum.React

const { quotes } = require('./quotes.json') 

class QuoteScreen extends Component { 
    state = { 
    QuoteIndex: 0 
    } 
    render() { 
    return (
     <Image ...> 
     <View ...> 
      ... 
      <ButtonNextQuote 
      onPress={() => { 
       this.setState((prevState, props) => { 
       return { 
        QuoteIndex: (prevState.QuoteIndex + 1) % (quotes.length - 1) 
       } 
       }) 
      }} 
      /> 
     </View> 
     </Image> 
    ) 
    } 
} 

o onPress içinde state güncellenmesini azaltmak mümkün olabilir mi:

bu RN kodunu var mı?

Anonim bir işlevi iki kez çağırmaktan kaçınmak, ancak bir işleyiciye başvuruda bulunmak ve bağlanmak istemezsiniz. Ayrıca, return

cevap

3

İşte bunu yapayım nasıl. SetState'in geriçağırımının (prevState) ilk argümanında object destructuring'u kullandım ve performans nedenleriyle anonim olmak yerine ayrı bir işlev kullandım. Ayrıca, işlev için this işlevini manuel olarak ayarlamam gerektiğinden, bunun için bir ok işlevi kullandığımı lütfen unutmayın.

+2

Bu soru ES6 ile etiketlendiğinden, deneysel özellikler (public class fields) kullandığınızı ve bunları etkinleştirmek için yapılması gerekenleri kısaca açıkladığınızı belirtmek faydalı olabilir. –

+0

Üzgünüm, benim hatam.Temel olarak, yaratma-tepki-app ve tepki-yerli bağımlılıkları listesine entegre edilmiş en yeni babel sürümü ile kutunun dışında bu özellik var. Bu E6 +, işaret ettiğin için teşekkürler –

8

'u kullanmaktan kaçınmak isterim. Güncelleme fonksiyonunu sınıfın dışındaki bir değişkende saklarım, örn.

const newState = ({QuoteIndex: i}) => ({QuoteIndex: (i + 1) % nQuotes}); 

(tabii ki değil inlined değilse artık senin için de önemlidir, sizin gibi herhangi bir şekilde belki "terseness" fonksiyonunu tanımlamak için seçebilir) Ve sonra yapabilirsiniz sadece this.setState(newState) çağırır:

onPress={() => this.setState(newState)} 
1

const { quotes } = require('./quotes.json') 
 

 
class QuoteScreen extends Component { 
 
    state = { 
 
    QuoteIndex: 0 
 
    } 
 

 
    handleUpdateState =() => { 
 
    this.setState(({ QuoteIndex }) => ({ 
 
     QuoteIndex: (QuoteIndex + 1) % (quotes.length - 1) 
 
    })); 
 
    } 
 

 
    render() { 
 
    return (
 
     <Image ...> 
 
     <View ...> 
 
      ... 
 
      <ButtonNextQuote 
 
      onPress={this.handleUpdateState} 
 
      /> 
 
     </View> 
 
     </Image> 
 
    ) 
 
    } 
 
}
Bunu yapmak için popüler ve iyi bir şekilde toplu bazı garip durumlardan kaçınmak için this.setState için bir geri arama sağlayarak

  1. Kullanım "işlevsel setState" olduğunu düşünüyorum durum güncelleştirmeleri

  2. "durum değişikliklerini bileşen sınıflarından ayrı olarak bildir" Yeni durumu alan fonksiyonlarda ayrı olarak tekrar test edilebilir. Dan Abramov tarafından tweets içeren bu yaklaşımın büyük bir açıklama için

onay this article

Örnek:

const { quotes } = require('./quotes.json') 

// keep pure function outside component to be reusable, testable 
const getQuoteIndex = ({ QuoteIndex }) => ({ 
    QuoteIndex: (QuoteIndex + 1) % (quotes.length - 1) 
}) 

class QuoteScreen extends Component { 
    state = { 
    QuoteIndex: 0 
    } 
    // arrow function will take care of this binding 
    handlePress =() => { this.setState(getQuoteIndex) } 
    render() { 
    return (
     <Image ...> 
     <View ...> 
      ... 
      <ButtonNextQuote 
      onPress={this.handlePress} 
      /> 
     </View> 
     </Image> 
    ) 
    } 
} 
1

Sen gibi her seferinde olay işleyicisi render ishal yeniden tanımlanması önlemek isterdim diğerleri söylediler. Bunun yerine bir geri arama işlevinin setState bir nesneyi geçmesi tercih: devlet nereden geldiğini bunun açık olduğundan

_handlePress =() => { 
    this.setState({ 
    QuoteIndex: (this.state.QuoteIndex + 1) % (quotes.length - 1) 
    }); 
}; 

onPress={this._handlePress} 

Bu okumak daha kolaydır. Ayrıca, fazladan geri arama işlevlerini izlemeniz gerekmez.