Проблема с reacts и setState (асинхронный)

У меня есть проблема с react js и с setState в документации он говорит, что он асинхронный. И проблема, которая у меня есть, состоит в том, что я использую Select, и согласно стоимости, которую он выбирает, он делает просьбу с ajax в базу данных, но как асинхронная стоимость, он не послан, когда первый раз кликает в выборе, если не до следующего click в любом выборе.

Как я делаю, чтобы посылать обновленную стоимость? Я увидел, что setState я могу получать второй аргумент, который является callBack, но не уверен как обновлять стоимость.

       class HttpPeticion extends React.Component{
  constructor(props){
   super(props);
   this.state={lista:[],
              showData:false,showNodata:false,
              cantidadResultados:'',
              errorTipo:'',errorBool:false
            };
    }

 handlerData(data){

   if (typeof data=="undefined") return 0;

  let errorTipo=data.tipo;
  let errorBool=data.error;

  if(errorBool){
     this.setState({errorBool:data.error})
     this.setState({errorTipo:data.tipo})
  }
  else{
    let recordSize= data.records.length;
      if(recordSize<= 0) {
         this.setState({showData:false})//ocular resultados
         this.setState({showNodata:true})//muestra "no hay datos"
       }else{
        this.setState({showData:true});//mostrar resultados
        this.setState({showNodata:false})//ocultar "no hay datas"
        this.setState({lista:data.records});
      }
    this.setState({cantidadResultados:recordSize + ' Coincidencias' });
 }

 }


    componentWillReceiveProps(){
    axios.post(this.props.urlServer,{'tipo':this.props.tipo,'nombre':this.props.nombre})
      .then(res => {
         this.handlerData(res.data.data);
      })
      .catch(function (error) {
         console.log(error);
      });
}


render(){
  return (
      <div>
         <div>{this.state.cantidadResultados}  </div>
         <div className={this.state.showData ? '': 'hidden' }>
            <ResultadoBusqueda datos={this.state.lista} />
          </div>

           <div className={this.state.showNodata ? '' : 'hidden'}>
             <h1>No hay ningun resultado </h1>
           </div>

           <div className={this.state.errorBool ? '':'hidden'}>
                <p>Un error ha ocurrido conectado con el ser servidor intente refresar la pagina(f5), si el problema
                     persiste contacte con el administrador.<a href="#">Mas informacion</a>  </p>
                <small>{this.state.errorTipo}</small>
           </div>
      </div>
  );
}
}

class ResultadoBusqueda extends React.Component{
    render(){
       return(
           <table>
              <thead>
                 <tr>
                  <th>Cuenta</th>
                  <th>Nombre</th>
                  <th>Precio</th>
                 </tr>
               </thead>
             <tbody>
            {
                 this.props.datos.map((item)=>{
                    return(
                       <tr key={item.cuenta.toString()}>
                       <td>{item.cuenta} </td>
                       <td>{item.nombre}</td>
                       </tr>
                    )
                 })
                }
            </tbody>
            </table>
      );
    }

}

class BusquedaAlumno extends React.Component {
setField (e) {
   //this.checkInput(e.target.value);
  this.setState({[e.target.name]: e.target.value})
}

render() {
   return (
      <div>

      <input type="text"
        onChange={(e)=>this.setField(e)}
        onKeyUp={(e)=>this.setField(e)}
        name="valor1"
       />
       <select onChange={(e)=>this.setField(e)} value={this.state.value} name="combo">
        <option value="-1">Selecciones</option>
         <option value="1">1</option>
         <option value="0">0</option>
       </select>

             <div>{this.state.valor1}</div>
              <div>{this.state.combo}</div>
         <HttpPeticion tipo={this.state.combo} nombre={this.state.valor1} urlServer={"http://localhost/viaLacteaQueryBusquedaId.php"} />
       </div>
    );
  }

Если он показывает мне данные, но у него есть этот маленький недостаток с select и textbox

1
задан 29.12.2016, 23:44
0 ответов

Ты должен отчитываться себе, что, если что-то не соответствует в твоей разработке, ты главным образом делаешь что-то плохим. Кроме того у тебя есть набор плохих практик, которые ты осуществляешь:

  • HttpPeticion: невидимый компонент? я предполагаю, что ты только делаешь просьбы в сервер с этим компонентом, если это так! Плохой!. Ты был бы должен создавать этот компонент как услуга, что только encarge просьб и упрощать использование url.
  • Не имеет смысл, что сначала establescas ты оценил, и потом делать запрос, Сначала ты должен делать запрос и потом deacuerdo в ответ заставлять устанавливать или нет избранную стоимость
  • Использовать string как свойство и наоборот e.target.name и name="valor1", установи единственную стоимость, для которого это будет признак name уже будьте в состоянии или из-за переменных
  • Изолировать действия для того, чтобы твой код был масштабируемым, отделять события input тех select никогда ты не будешь знать, когда ты должен применяться более логическая к твоим событиям

В conclución в твой вопрос и по причинам, которые я дал тебе, я написал бы твой компонент таким образом более или менее завися твоя необходимость

import HttpPeticion from 'services/HttpPeticion';

class BusquedaAlumno extends React.Component {
  componentWillMount() {
    this.setState({
      selectValue: '',
      inputValue: '',
    });
  }

  onInputChange() {
    this.setState({
      inputValue: e.target.value
    });
  }

  onSelectChange(e) {
    HttpPeticion.get('http://localhost/viaLacteaQueryBusquedaId.php', (data) => {
      this.setState({
        selectValue: e.target.value
        data: data
      });
    });
  }


  render() {
    const { inputValue, selectValue } = this.state;

    return (
      <div>
        <input type="text" onChange={this.onInputChange} value={inputValue} />

        <select onChange={this.onSelectChange} value={selectValue} >
          <option value="-1">Selecciones</option>
          <option value="1">1</option>
          <option value="0">0</option>
        </select>

        <div>{inputValue}</div>
        <div>{selectValue}</div>
       </div>
    );
  }
}
2
ответ дан 03.12.2019, 17:56

Метод setState класса Component согласись callback как второй параметр работать, когда уже станет отвечающим совремнным требованиям состояние.

this.setState({ [e.target.name]: e.target.value }, () => {
  // estado actualizado, hacer algo
});

В callback ты можешь помещать любую логику, которая зависела бы от успеха обновления того ввода состояния.

1
ответ дан 03.12.2019, 17:56

Кроме рекомендаций @JoseAPL, Есть проблема в handler, который обновляет состояние, из-за каждого неудара в лунку или select, что обновляет состояние, в действительности ты не обновляешь состояние, эти remplazando полностью, так что, сделав это.

setField (e) {
    this.setState({[e.target.name]: e.target.value})
}

эти remplazando все состояние и оставляя это только с полем, которое становится отвечающим современным требованиям в этом мгновении, удаляя предыдущее поле, решение состоит в том, чтобы использовать Иммутабилити Ельперс React.

Сначала имеет значение книжный магазин

import update from 'react-addons-update'

Потом определи твой handler таким образом.

setField (e) {
    this.setState(update(
        this.state,
        {[e.target.name]: {$set: e.target.value}}
    ))
}

Как хорошая практика всегда использует Иммутабилити Ельперс для mutar state.

1
ответ дан 03.12.2019, 17:56