反应:元素为true时无法显示按钮

时间:2020-09-17 04:20:18

标签: reactjs if-statement react-props

这是我的代码:

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 && <button>Agregar</button>}
    </div>
  );
}

我想做的是,当输入有东西输入时,属性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>
    );
  }

2 个答案:

答案 0 :(得分:0)

问题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

反应组件状态生命周期。尝试在入队的同一反应周期内引用入队状态。您需要排队的值,直到 next 渲染周期才可用。

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, // <-- *
  });
}

* length == 0是错误的,length!== 0是真实的,并且被强制转换为布尔值(!!

解决方案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更简单直接。

答案 1 :(得分:0)

这就是您使用组件的方式

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