Реагировать: не удается отобразить кнопку, когда элемент имеет значение true

#reactjs #if-statement #react-props

#reactjs #if-оператор #реагировать-реквизит

Вопрос:

это мой код:

 const Agregar = ({inputPregunta, validatePregunta}) => {
  
  return(
    <div id="content">
      <h2>¿Cual es tu pregunta?</h2>
      <input id="valorPregunta" type="text" placeholder="Añade aqui tu pregunta..." onChange={(e) => inputPregunta(e)}/>
      {validatePregunta amp;amp; <button>Agregar</button>}
    </div>
  );
}
  

То, что я пытаюсь сделать, это когда на входе что-то введено, prop validatePregunta (по умолчанию false) принимает значение true, и отображается элемент button, для этого я попытался выполнить метод в App.js файл, подобный этому:

 actualizarPregunta = (e) => {
    this.setState({inputPregunta: e.target.value})
    
    if(this.state.inputPregunta.trim().length > 0){
      this.setState({validatePregunta: true})
    } else {
      this.setState({validatePregunta: false})
    }
  }
  

Но ничего не показывает, есть ли что-то, что я делаю неправильно?

Редактировать: вот код рендеринга для реквизита:

 renderRoute = () => {
    switch(this.state.route) {
      case 'menu':
        return (
          <div>
            <Header />
            <Agregar inputPregunta={this.actualizarPregunta} validate={this.state.validatePregunta}/>
            <Publications />
          </div>
        )
      default :
        return (
          <div>
            <Header />
            <Publications />
          </div>
        )
    }
  }
  
  render() {
    return (
      <div>
        {
          this.renderRoute(this.state.route)
        }
      </div>
    );
  }
  

Комментарии:

1. Можете ли вы обновить вопрос, включив в него рендеринг кода родительского компонента Agregar , чтобы мы могли видеть, как состояние validatePregunta передается в качестве реквизита, или попытаться проверить actualizarPregunta , вызывается ли для обновления состояния?

2. Добавлено рисование! Спасибо за предложение!

Ответ №1:

Вот как вы используете compoennt

 <Agregar inputPregunta={this.actualizarPregunta} validate={this.state.validatePregunta}/>
  

вы передаете значение this.state.validatePregunta по имени свойства validate

и тогда вы ожидаете чего-то validatePregunta в компоненте Agregar , но это должно быть на самом деле validate

 const Agregar = ({inputPregunta, validatePregunta}) => { //incorrect

const Agregar = ({inputPregunta, validate}) => { //correct
  

ИЛИ просто измените имя реквизита, как показано ниже

 <Agregar inputPregunta={this.actualizarPregunta} validatePregunta={this.state.validatePregunta}/>
  

И вы должны изменить actualizarPregunta , как только вы обновите состояние, оно не обновляет значение состояния в реальном времени, это асинхронный процесс, поэтому this.state.inputPregunta.trim() он даст вам значение непосредственно перед обновлением, поэтому измените его так, и мне нравится, как @Drew Reese обрабатывает эту часть

 actualizarPregunta = (e) => {
    const newValue = e.target.value;
    this.setState({inputPregunta: newValue })

    if(newValue.trim().length > 0){
      this.setState({validatePregunta: true})
    } else {
      this.setState({validatePregunta: false})
    }
  }
  

Ответ №2:

Проблема 1

Реквизиты не выровнены.

Подпись компонента есть, const Agregar = ({inputPregunta, validatePregunta}) но вы проходите validate={this.state.validatePregunta} .

 <Agregar
  inputPregunta={this.actualizarPregunta}
  validate={this.state.validatePregunta}
/>
  

Решение

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

 <Agregar
  inputPregunta={this.actualizarPregunta}
  validatePregunta={this.state.validatePregunta}
/>
  

Проблема 2

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

 actualizarPregunta = (e) => {
  this.setState({ inputPregunta: e.target.value }); // <-- state update enqueued

  if (this.state.inputPregunta.trim().length > 0){ // <-- current state value
    this.setState({ validatePregunta: true })
  } else {
    this.setState({ validatePregunta: false })
  }
}
  

Решение 1

Поставьте обновление состояния в очередь и используйте текущее значение события для установки другого состояния

 actualizarPregunta = (e) => {
  const { value } = e.target;
  this.setState({
    inputPregunta: value,
    validatePregunta: !!value.trim().length, // <-- *
  });
}
  

* длина == 0 является ложной, длина !== 0 является истинной и принудительно преобразуется в boolean ( !! )

Решение 2

Поставьте в очередь обновление состояния и используйте componentDidUpdate функцию жизненного цикла для обработки эффекта

 actualizarPregunta = (e) => {
  const { value } = e.target;
  this.setState({ inputPregunta: value });
}

componentDidUpdate(prevProps, prevState) {
  const { inputPregunta } = this.state;
  if (prevState.inputPregunta !== inputPregunta) {
    this.setState({ validatePregunta: !!inputPregunta.trim().length });
  }
}
  

Решение № 1 является более простым и простым.