Поиск…


Основное состояние

Компоненты State in React необходимы для управления и передачи данных в вашем приложении. Он представлен как объект JavaScript и обладает областью уровня компонента , его можно рассматривать как частные данные вашего компонента.

В приведенном ниже примере мы определяем некоторое начальное состояние в constructor функции нашего компонента и используем его в функции 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 ()

Основной способ, которым вы делаете обновления пользовательского интерфейса для своих приложений React, - это вызов функции setState() . Эта функция будет выполнять мелкое слияние между новым состоянием, которое вы предоставляете, и предыдущим состоянием, и вызовет повторную визуализацию вашего компонента и всех его дециентов.

параметры

  1. updater : Это может быть объект с несколькими парами ключ-значение, которые должны быть объединены в состояние или функцию, возвращающую такой объект.
  2. callback (optional) : функция, которая будет выполнена после того, как setState() выполнена успешно. Из-за того, что setState() не гарантируется, что React является атомарным, иногда это может быть полезно, если вы хотите выполнить какое-либо действие после того, как вы setState() что setState() успешно выполнен.

Использование:

setState метод принимает программу updater аргумента , который может быть либо объектом с рядом ключом-значением-пар , которые должны быть объединены в состояние, или функцией , которая возвращает такой объект , вычисленный из prevState и props .

Использование setState() с объектом как средство 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() с функцией в качестве средства 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
  };
});

Это может быть безопаснее, чем использование аргумента объекта, в котором используются множественные вызовы для setState() , поскольку несколько вызовов могут быть собраны вместе с помощью React и выполняться сразу, и это предпочтительный подход при использовании текущих реквизитов для установки состояния.

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

Эти вызовы могут быть объединены путем React с использованием Object.assign() , в результате чего счетчик увеличивается на 1, а не на 3.

Функциональный подход также может использоваться для перемещения логики настройки состояния вне компонентов. Это позволяет изолировать и повторно использовать логику состояния.

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

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

// Within component

this.setState(incrementCounter);

Вызов функции setState() с объектом и функцией обратного вызова

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

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

Общий антипаттерн

Вы не должны сохранять props в state . Он считается анти-шаблоном . Например:

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

url prop сохраняется в state а затем изменен. Вместо этого выберите сохранение изменений в состоянии, а затем постройте полный путь, используя как state и 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>
        )
    }
}

Это связано с тем, что в приложении React мы хотим иметь единственный источник правды - т.е. все данные являются ответственностью одного единственного компонента и только одного компонента. Ответственность этого компонента заключается в сохранении данных в его состоянии и распространении данных на другие компоненты через реквизиты.

В первом примере как класс MyComponent, так и его родительский элемент поддерживают «url» в своем состоянии. Если мы обновим state.url в MyComponent, эти изменения не будут отражены в родительском. Мы потеряли наш единственный источник правды, и становится все труднее отслеживать поток данных через наше приложение. Сравните это со вторым примером - url поддерживается только в состоянии родительского компонента и используется в качестве опоры в MyComponent - поэтому мы сохраняем единый источник правды.

Состояние, события и управляемые элементы управления

Вот пример компонента React с «управляемым» полем ввода. Всякий раз, когда изменяется значение поля ввода, вызывается обработчик событий, который обновляет состояние компонента с новым значением поля ввода. Вызов setState в обработчике событий вызовет вызов для render обновления компонента в 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'));

Очень важно отметить поведение во время работы. Каждый раз, когда пользователь меняет значение в поле ввода

  • handleChange будет вызван и так
  • setState будет вызываться и так
  • render будет вызван

Pop quiz, после ввода символа в поле ввода, с помощью которого элементы DOM изменяются

  1. все из них - верхний уровень div, легенда, вход, h1
  2. только вход и h1
  3. ничего такого
  4. Что такое DOM?

Вы можете поэкспериментировать с этим больше здесь, чтобы найти ответ



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow