Почему мой экран не обновляется, когда я нажимаю кнопку в первый раз, но впоследствии прекрасно работает? - PullRequest
0 голосов
/ 01 мая 2019

Я впервые делаю конечные автоматы.Я попытался создать программу типа «стоп-сигнал», в которой, если вы нажмете кнопку, индикатор изменится один раз, начиная с зеленого, затем с желтого, если щелкнуть снова, а затем с красным, перед повторным циклом.Мне удалось заставить его работать, за исключением одного небольшого бага.Его нужно дважды щелкнуть перед обновлением экрана, и я не знаю, как это исправить.

Я заметил на своей консоли, что currentLightState изменяется при нажатии на него, но возвращается к предыдущемуцвет на первый клик.Я понял, что это потому, что он не синхронизирован с моим состоянием.Однако, когда я пытаюсь поместить currentLightState внутри класса и назначить this.state.light, currentLightState становится неопределенным.Я попытался добавить .bind (this) в конце this.state.light, но я просто получаю еще одну ошибку, говоря, что это не функция.Любые предложения?

Я не опубликовал свою функцию обновления или функцию onHandleClick, поскольку она не имеет непосредственного отношения к currentLightState.

const lightMachine = {
  green:{
    LIGHT: 'yellow'
  },
  yellow:{
    LIGHT: 'red'
  },
  red:{
    LIGHT: 'green'
  }
}

// current location of currentLightState
let currentLightState = 'green';
class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
          light: 'green'    //initial value
        };
      }
    transition(state, action){
      // This is where my currentLightState messes up the first run 
      currentLightState = this.state.light

      const nextLightState =  lightMachine[currentLightState][action]
      this.setState({light: nextLightState}) 
    }
    render(){

        return(
            <div>
              <button onClick={this.onHandleClick.bind(this)}>
                change the Light!
              </button>
                {currentLightState}
            </div>
            );
        }
    }

РЕДАКТИРОВАТЬ: Вот моя функция onHandleClick:)

    onHandleClick(){
      this.update(currentLightState)

    };

также, я думаю, я решил свою проблему, просто заменив currentLightState в функции рендеринга this.state.light.

Idk, если это допустимое исправление или нет, но онокажется, работает в настоящее время.

было бы неплохо, хотя, если бы кто-то еще мог ответить, почему, когда вы помещаете currentLightState в класс и присваиваете ему state.light, он становится неопределенным.Это помогло бы расширить мои знания React:)

1 Ответ

0 голосов
/ 01 мая 2019

Добро пожаловать на доски Jr194!

По теме, я думаю, будет полезно сохранить currentLight и lightMachine в качестве значений, управляемых состоянием вашего компонента.Это помогает гарантировать, что вся ваша логика находится в одном и том же контексте, избегая таких странных ошибок, как «бла-бла не определено».

Во-вторых, вы, похоже, определили несколько функций, которые действительно можно сузить до одной.update, onHandleClick и transition все, кажется, пытаются сделать то же самое.

Наконец, рассмотрите возможность реорганизации кода в lightMachine, чтобы он был немного более интуитивным, чтобы вы могли быстро перейти к следующемусвет.Вы уже знаете, какой текущий цвет у родительского ключа, действительно ли необходимо, чтобы его объект содержал другой ключ с тем же значением?

Рассмотрим следующий код:

class App extends React.Component {
  state = {
    currentLight: "green",
    lightMachine: {
      green: {
        nextLight: "yellow"
      },
      yellow: {
        nextLight: "red"
      },
      red: {
        nextLight: "green"
      }
    }
  };

  transition = () => {
    const currentLight = this.state.currentLight;
    const nextLight = this.state.lightColors[currentLight].nextLight;
    this.setState({
      currentLight: nextLight
    });
  };
  render() {
    return (
      <div>
        <button onClick={this.transition}>Click Me</button>
        <div>{this.state.currentLight}</div>
      </div>
    );
  }
}

Это должно позволить вам быстро изменить свет, как и ожидалось.И вот песочница: https://codesandbox.io/s/4x08ovyjp7

Дайте мне знать, если у вас есть какие-либо вопросы:)

Также относительно вашего вопроса о том, почему currentLightState выдает ошибку в вашем render, когда выпоместите это в класс.Это не проблема React, это проблема JavaScript.

Давайте рассмотрим несколько примеров:

const test= "hello"
class Example extends React.Component{
   state = {
       greeting: "woof"
   }
   render(){
     <div>{test}</div>
   }
}

Как вы знаете, это не даст нам никакой ошибки.Мы подключаемся к переменной, которая определена вне нашего класса, и это совершенно нормально.

Теперь давайте посмотрим на это

class Example extends React.Component{
   state = {
       greeting: "woof"
   }

   test = this.state.greeting

   render(){
     <div>{test}</div>
   }
}

Это дает нам ошибку.Почему, потому что в вашем методе рендеринга вы рассматриваете тест как переменную, а не так.В class объекте, подобном тому, который вы написали, currentLightState и теперь test обрабатываются как properties, а не как переменные.Чтобы получить доступ к свойству внутри класса, вам нужно использовать ключевое слово "this", то, что вы уже делали с this.update, this.handleOnClick и т. Д., Которые также являются свойствами.

Теперь мы знаем, что этот код будет работать.

class Example extends React.Component{
   state = {
       greeting: "woof"
   }

   test = this.state.greeting

   render(){
     <div>{this.test}</div>
   }
}
...