Zoeken…


Basisstaat

State in React-componenten zijn essentieel voor het beheren en communiceren van gegevens in uw applicatie. Het wordt weergegeven als een JavaScript-object en heeft een bereik op componentniveau , het kan worden gezien als de privégegevens van uw component.

In het onderstaande voorbeeld definiëren we een beginstatus in de constructor van onze component en maken we hiervan gebruik in de render .

class ExampleComponent extends React.Component {
  constructor(props){
    super(props);

    // Set-up our initial state
    this.state = {
      greeting: 'Hiya Buddy!'
    };
  }

  render() {
    // We can access the greeting property through this.state
    return(
      <div>{this.state.greeting}</div>
    );
  }
}

setstate ()

De primaire manier waarop u UI-updates voor uw React-toepassingen setState() is via een aanroep van de functie setState() . Deze functie voert een ondiepe samenvoeging uit tussen de nieuwe status die u opgeeft en de vorige status, en activeert een nieuwe weergave van uw component en alle afstammelingen.

parameters

  1. updater : het kan een object zijn met een aantal sleutel / waarde-paren dat moet worden samengevoegd in de status of een functie die een dergelijk object retourneert.
  2. callback (optional) : een functie die wordt uitgevoerd nadat setState() met succes is uitgevoerd. Vanwege het feit dat aanroepen van setState() niet door React worden gegarandeerd als atomair, kan dit soms handig zijn als u een actie wilt uitvoeren nadat u zeker weet dat setState() met succes is uitgevoerd.

Gebruik:

De methode setState accepteert een updater argument dat een object kan zijn met een aantal sleutel / waarde-paren die moeten worden samengevoegd in de status, of een functie die een dergelijk object retourneert dat is berekend op basis van prevState en props .

setState() met een object als updater

//
// An example ES6 style component, updating the state on a simple button click.
// Also demonstrates where the state can be set directly and where setState should be used.
//
class Greeting extends React.Component {
    constructor(props) {
        super(props);
        this.click = this.click.bind(this);
        // Set initial state (ONLY ALLOWED IN CONSTRUCTOR)
        this.state = {
            greeting: 'Hello!'
        };
    }
    click(e) {
        this.setState({
              greeting: 'Hello World!'
        });
    }
    render() {
        return(
            <div>
                <p>{this.state.greeting}</p>
                <button onClick={this.click}>Click me</button>
            </div>
        );
    }
    
}

setState() met een functie als updater

//
// This is most often used when you want to check or make use 
// of previous state before updating any values.
//

this.setState(function(previousState, currentProps) {
  return {
    counter: previousState.counter + 1
  };
});

Dit kan veiliger zijn dan het gebruik van een objectargument waarbij meerdere aanroepen naar setState() worden gebruikt, omdat meerdere aanroepen kunnen worden gebatcht door React en tegelijkertijd kunnen worden uitgevoerd, en dit is de voorkeursbenadering bij het gebruik van huidige rekwisieten om de status in te stellen.

this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });

Deze aanroepen kunnen aan elkaar worden Object.assign() door Object.assign() met Object.assign() , waardoor de teller wordt verhoogd met 1 in plaats van 3.

De functionele benadering kan ook worden gebruikt om de statusinstellingslogica buiten de componenten te plaatsen. Dit maakt isolatie en hergebruik van toestandslogica mogelijk.

// Outside of component class, potentially in another file/module

function incrementCounter(previousState, currentProps) {
    return {
        counter: previousState.counter + 1
    };
}

// Within component

this.setState(incrementCounter);

setState() aanroepen met een object en een callback-functie

//
// 'Hi There' will be logged to the console after setState completes
//

this.setState({ name: 'John Doe' }, console.log('Hi there'));

Gemeenschappelijke Antipattern

Je moet props in een state bewaren. Het wordt beschouwd als een anti-patroon . Bijvoorbeeld:

export default class MyComponent extends React.Component {
    constructor() {
        super();

        this.state = {
            url: ''
        }

        this.onChange = this.onChange.bind(this);
    }

    onChange(e) {
        this.setState({
            url: this.props.url + '/days=?' + e.target.value
        });
    }

    componentWillMount() {
        this.setState({url: this.props.url});
    }

    render() {
        return (
            <div>
                <input defaultValue={2} onChange={this.onChange} />

                URL: {this.state.url}
            </div>
        )
    }
}

De prop- url wordt opgeslagen in de state en vervolgens gewijzigd. Kies in plaats daarvan om de wijzigingen in een status op te slaan en vervolgens het volledige pad samen te stellen met zowel de state als de props :

export default class MyComponent extends React.Component {
    constructor() {
        super();

        this.state = {
            days: ''
        }

        this.onChange = this.onChange.bind(this);
    }

    onChange(e) {
        this.setState({
            days: e.target.value
        });
    }

    render() {
        return (
            <div>
                <input defaultValue={2} onChange={this.onChange} />

                URL: {this.props.url + '/days?=' + this.state.days}
            </div>
        )
    }
}

Dit komt omdat we in een React-toepassing één enkele bron van waarheid willen hebben - dat wil zeggen dat alle gegevens de verantwoordelijkheid zijn van één enkele component en slechts één component. Het is de verantwoordelijkheid van dit onderdeel om de gegevens in zijn staat op te slaan en de gegevens via rekwisieten naar andere componenten te distribueren.

In het eerste voorbeeld behouden zowel de MyComponent-klasse als de bovenliggende 'url' binnen hun status. Als we state.url bijwerken in MyComponent, worden deze wijzigingen niet doorgevoerd in het bovenliggende item. We hebben onze enige bron van waarheid verloren en het wordt steeds moeilijker om de gegevensstroom door onze applicatie te volgen. Vergelijk dit met het tweede voorbeeld - url wordt alleen gehandhaafd in de staat van de bovenliggende component en gebruikt als een prop in MyComponent - we handhaven daarom een enkele bron van waarheid.

Status, gebeurtenissen en beheerde controles

Hier is een voorbeeld van een React-component met een "beheerd" invoerveld. Wanneer de waarde van het invoerveld verandert, wordt een gebeurtenishandler aangeroepen die de status van de component bijwerkt met de nieuwe waarde van het invoerveld. De oproep tot setState bij handler bellen leiden tot render bijwerken van de component in de dom.

import React from 'react';
import {render} from 'react-dom';


class ManagedControlDemo extends React.Component {

  constructor(props){
    super(props);
    this.state = {message: ""};
  }

  handleChange(e){
    this.setState({message: e.target.value});
  }

  render() {
    return (
      <div>
        <legend>Type something here</legend>
          <input 
            onChange={this.handleChange.bind(this)} 
            value={this.state.message} 
            autoFocus />
        <h1>{this.state.message}</h1>
      </div>
   );
  } 
}


render(<ManagedControlDemo/>, document.querySelector('#app'));

Het is heel belangrijk om het runtime-gedrag op te merken. Elke keer verandert een gebruiker de waarde in het invoerveld

  • handleChange wordt aangeroepen en zo
  • setState zal worden genoemd en zo
  • render zal worden genoemd

Pop quiz, nadat u een teken in het invoerveld typt, welke DOM-elementen veranderen

  1. al deze - het hoogste niveau div, legend, input, h1
  2. alleen de invoer en h1
  3. niets
  4. wat is een DOM?

Je kunt hier meer mee experimenteren om het antwoord te vinden



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow