Реагировать: состояние не срабатывает, возврат

Это компонент:

import React from 'react';
const ContactCard = ({contact, onFormSubmit}) => {

    this.state = {modal: 'block'};

    const handleSubmit = (e) => {
        onFormSubmit(contact);
    };

    const showModal = (e) => {
        if (this.state.modal === 'block') {
            this.state.modal = 'none';
        } else {
            this.state.modal = 'block';
        }
        console.info(this.state.modal);
    };

    return (
        <div>
            <input type = "checkbox" onClick = {handleSubmit} />
            <div>
                <button onClick = {showModal}>Open Modal</button>
                <div style = { { display: this.state.modal } }>
                    <h2>The text</h2>
                </div>
            </div>
            <div className = "clearfix"></div>
        </div >
    )
}

export default ContactCard;

Что происходит, когда я нажимаю кнопку, showModal срабатывает, и это правильно. Но style = {{display: this.state.modal}} не меняется на block или none. Что здесь не так?

Вы не присваиваете значение государству напрямую. Вы должны использовать this.setState({ 'modal': 'block' }) вместо this.state.modal='block'

dealwap 18.10.2018 21:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
95
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Используйте метод setState, если вы хотите обновить свое состояние, никогда не устанавливайте свое состояние напрямую как this.state.something == .... Так,

const showModal = e => {
  if (this.state.modal === "block") {
    this.setState({ modal: "none" });
  } else {
    this.setState({ modal: "block" });
  }
};

Кроме того, не следует сразу записывать свое состояние таким образом, поскольку оно асинхронное. Вы не можете увидеть такое состояние обновлений. Для setState есть функция обратного вызова, но вы можете легко зарегистрировать свое состояние в методе рендеринга.

render(){
    console.info( this.state.modal );
    return( ... );
}

Я не заметил, когда в первый раз покупал, что ваш компонент является функциональным, поэтому вы не можете использовать там this.state. Просто определите его как классный.

class ContactCard extends React.Component {
  state = { modal: "block" };

  showModal = () => {
    if ( this.state.modal === "block" ) {
      this.setState({ modal: "none" });
    } else {
      this.setState({ modal: "block" });
    }
  };

  render() {
    console.info( this.state.modal );
    return (
      <div>
        <div>
          <button onClick = {this.showModal}>Open Modal</button>
          <div style = {{ display: this.state.modal }}>
            <h2>The text</h2>
          </div>
        </div>
        <div className = "clearfix" />
      </div>
    );
  }
}

export default ContactCard;
Uncaught TypeError: _this.setState is not a function - вот что я получаю :(
AmazingDayToday 18.10.2018 21:46

Определите свой компонент как компонент класса. Кроме того, вы используете поля класса, поэтому вам не нужно определять свое состояние, например this.state, просто пропустите это и перейдите к state = { modal: "block"}.

devserkan 18.10.2018 21:48

Лол, голос против. Можно сказать, чтобы улучшить свой ответ, а не отрицать его. Поскольку моя первая часть ответа решает проблему. Помогать SO сейчас сложно. @AmazingDayToday, я обновил свой ответ.

devserkan 18.10.2018 21:57

Вы создали функциональный компонент. Функциональные компоненты не имеют доступа к состоянию.

Я бы рекомендовал прочитать это руководство с разделов 4 по 5: https://reactjs.org/docs/components-and-props.html

Вторая проблема заключается в том, что вы пытаетесь установить состояние напрямую через присваивание.

this.state.modal === 'block' . // Incorrect

Вместо этого вы должны использовать this.setState({ modal: 'block' }).

Хорошо 1.) данные в response хранятся в состоянии, которое доступно только в компоненте на основе класса, убедитесь, что всякий раз, когда вам требуется состояние в компоненте, создавайте этот класс компонента на основе. 2.) Никогда не изменяйте состояние напрямую, для этого используется метод setState. 3.) Никогда не изменяйте напрямую массивы и объекты, так как это ссылочные типы.

Ответ принят как подходящий

Поскольку вы получаете доступ к состоянию и изменяете его, вам необходимо изменить свой функциональный компонент, чтобы реагировать на компонент класса, как показано ниже. Также вам нужно изменить состояние, и для этого вам нужно использовать setState, чтобы обновленное значение было отображено. seState - это метод для изменения значения состояния, и всякий раз, когда вы выполняете setState, ваш компонент будет отображаться один раз для каждого setState.

Если вы измените состояние как this.state.modal = 'block'; измененное значение не будет отображаться, и это не рекомендуется

import React from 'react';
class ContactCard extends React.Component{

constructor(props){
   super(props);
   this.state = {modal: 'block'}
}

showModal = e => {
    const { modal } = this.state;
    if (modal == 'block') {
        this.setState({modal: 'none'}, ()=> {
            console.info(modal);//this will print none here
        });

    } else {
        this.setState({modal : 'block'}, () => {
            console.info(modal);//this will print block here
        });
    }
};

render(){
 const { modal } = this.state;
 return (
    <div>
        <div>
            <button onClick = {this.showModal}>Open Modal</button>
            <div style = { { display: modal } }>
                <h2>The text</h2>
            </div>
        </div>
        <div className = "clearfix"></div>
    </div >
  )
 }
}

  export default ContactCard;

Другие вопросы по теме