Sök…


Grundtillstånd

State in React-komponenter är viktigt för att hantera och kommunicera data i din applikation. Det representeras som ett JavaScript-objekt och har komponentnivåomfång, det kan ses som din privata data för din komponent.

I exemplet nedan definierar vi ett visst initialt tillstånd i constructor för vår komponent och använder det i 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>
    );
  }
}

sets ()

Det primära sättet att du gör UI-uppdateringar för dina React-applikationer är genom ett samtal till setState() . Denna funktion kommer att utföra en grunt sammanslagning mellan det nya tillstånd som du tillhandahåller och det tidigare tillståndet och kommer att utlösa en återgivning av din komponent och alla decedents.

parametrar

  1. updater : Det kan vara ett objekt med ett antal nyckelvärdespar som ska slås samman till tillståndet eller en funktion som returnerar ett sådant objekt.
  2. callback (optional) : en funktion som kommer att setState() efter att setState() har genomförts framgångsrikt. På grund av det faktum att samtal till setState() inte garanteras av React att vara atomiska, kan detta ibland vara användbart om du vill utföra några åtgärder efter att du är setState() att setState() har genomförts framgångsrikt.

Användande:

setState metoden accepterar ett updater som antingen kan vara ett objekt med ett antal nyckelvärden-par som ska slås samman i tillståndet, eller en funktion som returnerar ett sådant objekt beräknat från prevState och props .

Använda setState() med ett objekt som 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>
        );
    }
    
}

Använda setState() med en funktion som 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
  };
});

Detta kan vara säkrare än att använda ett objektargument där flera samtal till setState() används, eftersom flera samtal kan samlas av React och exekveras samtidigt, och är den föredragna metoden när man använder nuvarande rekvisita för att ställa in tillstånd.

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

Dessa samtal kan samlas samman av React med hjälp av Object.assign() , vilket resulterar i att räknaren ökas med 1 snarare än 3.

Det funktionella tillvägagångssättet kan också användas för att flytta tillståndsinställningslogik utanför komponenterna. Detta möjliggör isolering och återanvändning av tillståndslogik.

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

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

// Within component

this.setState(incrementCounter);

Ringa setState() med ett objekt och en återuppringningsfunktion

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

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

Vanliga antipattern

Du bör inte spara props i state . Det anses vara ett antimönster . Till exempel:

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>
        )
    }
}

Prop- url sparas i state och ändras sedan. Välj istället för att spara ändringarna i ett tillstånd och bygg sedan upp hela sökvägen med både state och 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>
        )
    }
}

Detta beror på att vi i en React-applikation vill ha en enda sanningskälla - dvs all data är ansvaret för en enda komponent och bara en komponent. Det är denna komponents ansvar att lagra informationen i dess tillstånd och distribuera informationen till andra komponenter via rekvisita.

I det första exemplet upprätthåller både MyComponent-klassen och dess överordnade "url" i sitt tillstånd. Om vi uppdaterar state.url i MyComponent återspeglas inte dessa förändringar i överordnade. Vi har tappat vår enda sanningskälla och det blir allt svårare att spåra flödet av data genom vår applikation. Kontrast detta med det andra exemplet - url upprätthålls endast i tillståndet för moderkomponenten och används som en rekvisita i MyComponent - vi har därför en enda källa till sanning.

Tillstånd, händelser och hanterade kontroller

Här är ett exempel på en React-komponent med ett "hanterat" inmatningsfält. När värdet på inmatningsfältet ändras kallas en händelsehanterare som uppdaterar komponentens tillstånd med det nya värdet för inmatningsfältet. Uppmaningen till setState i händelsehanteraren kommer att utlösa en uppmaning att render uppdatera komponent i 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'));

Det är mycket viktigt att notera körbeteendet. Varje gång en användare ändrar värdet i inmatningsfältet

  • handleChange kommer att kallas och så
  • setState kommer att kallas och så
  • render kommer att kallas

Popquiz, när du har skrivit ett tecken i inmatningsfältet, vilka DOM-element ändras

  1. alla dessa - toppnivån div, legend, input, h1
  2. endast ingången och h1
  3. ingenting
  4. vad är en DOM?

Du kan experimentera med det här här för att hitta svaret



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow