В состоянии получить ответ, но не может отобразить реакцию - PullRequest
0 голосов
/ 02 мая 2018

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

Это мой строитель

this.getAddressFromLatLong = this.getAddressFromLatLong.bind(this)

Это функция, которую я написал для конвертации

getAddressFromLatLong(lat, long) 
{ Geocode.fromLatLng(lat, long).then( 
    response => { 
        const address = response.results[0].formatted_address; 
        console.log(address); 
        return address; 
    }, 
    error => { console.error(error); } 
)}

Здесь я отображаю адрес

return ( 
    <tr key={atData.uid}> 
        <td>{atData.uid}</td> 
        <td>{atData.user}</td> 
        <td><TimeStamp time={atData.dateTime} format='full' /></td> 
        <td>{this.getAddressFromLatLong(atData.latitude, atData.longtitude)}</td> 
    </tr> 
)

Пожалуйста, сообщите>. <</p>

Edit:

Я понял, что размещенного мною кода недостаточно, поэтому вот больше информации о моих проблемах и конечном продукте, который я хотел

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

Так я и сделал свой выпадающий список

componentWillMount() {
    const lockSelected = this.state.selectedLock
    console.log(lockSelected)
    // Calling the Lock List
    axios
        .get(process.env.REACT_APP_FIREBASE_DATABASE + '/' + doGetLocklist() + '.json?auth=' + process.env.REACT_APP_FIREBASE_DATABASE_SECRET)
        .then((response) => {
            // console.log("=== componentDidMount: axios - Lock List ===")
            this.setState({ locklistArray: response.data, loading: false })
        })
        .catch((err) => { })
}
renderDropdown() {
    return _.map(this.state.locklistArray, lockData => {
        return (
            <option value={lockData.uid}>{lockData.lockName}</option>
        )
    })
}

Вот так я выводю выпадающий список

<FormControl componentClass="select" placeholder="select" onChange={this.detectOnChangeEvent}>
    <option value="">- Please Select a lock -</option>
    {this.renderDropdown()}
</FormControl>

После этого, когда пользователь выберет блокировку, он запустит эту функцию deteOnChange, чтобы он заново отобразил таблицу с данными блокировки

detectOnChangeEvent(event) {
    this.setState({
        selectedLock: event.target.value,
    })
    this.fetchSelectedATData(event.target.value)
    this.forceUpdateHandler()
}

forceUpdateHandler() {
    this.forceUpdate();
};

fetchSelectedATData(atlist) {
    var lockSelected = atlist
    axios
        .get(process.env.REACT_APP_FIREBASE_DATABASE + '/' + doGetAuditTrailList() + '/' + lockSelected + '.json?auth=' + process.env.REACT_APP_FIREBASE_DATABASE_SECRET)
        .then((response) => {
            // console.log("=== componentDidMount: axios - User List ===")
            console.log(response.data)
            this.setState({ atArray: response.data, loading: false })
        })
        .catch((err) => { })

    this.renderATlistArray()
}

renderATlistArray() {
    if (this.state.loading) {
        return (<Loading />)
    } else {
        return _.map(this.state.atArray, atData => {
            return (
                <tr key={atData.uid}>
                    <td>{atData.uid}</td>
                    <td>{atData.user}</td>
                    <td><TimeStamp time={atData.dateTime} format='full' /></td>
                    <td>{this.getAddressFromLatLong(atData.latitude, atData.longtitude)}</td>
                </tr>
            )
        })
    }
}

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

Вот скриншот ответа

Надеюсь, со всей этой добавленной информацией вам, ребята, будет лучше понять код!

1 Ответ

0 голосов
/ 03 мая 2018

Есть несколько проблем с кодом, который вы отправили

  1. Как написано, getAddressFromLatLong() не имеет полезного возвращаемого значения. Он возвращает undefined, потому что он написан с использованием синтаксиса methodName() {} без оператора return.

    Вот как переписать его так, чтобы оно возвращало значение:

    getAddressFromLatLong (lat, long) { 
      return Geocode.fromLatLng(lat, long).then( 
        response => { 
          const address = response.results[0].formatted_address; 
          console.log(address); 
          return address; 
        }, 
        error => { console.error(error); } 
      )
    }
    
  2. getAddressFromLatLong() вызывает асинхронную функцию , которая возвращает Promise. Асинхронная функция не выдает значение сразу - вместо этого мы предоставляем обратный вызов , который в конечном итоге вызывается (в некоторый неизвестный момент в будущем), когда асинхронная функция в конечном итоге выдает значение.

    Обратный вызов - это просто обычная функция, которая вызывается в определенный момент в будущем с результатом асинхронной операции.

    A Promise - это способ представления асинхронной операции и регистрации обратных вызовов в зависимости от того, удалась операция или нет.

    Функция .then() позволяет нам регистрировать эти обработчики успеха и неудач. Первая функция, переданная в .then(), вызывается, если операция завершается успешно. Вторая функция вызывается в случае сбоя операции.

    Существуют и другие способы регистрации обработчиков в Promises: ознакомьтесь с MDN Docs для полного API.

Чтобы этот код работал, нам нужно запустить асинхронную операцию, а затем визуализировать компонент после того, как данные станут доступны.

Есть много способов справиться с этим, но самый простой - сохранить результат операции в состоянии компонента .

Вот один из способов переписать этот компонент, чтобы он отображал асинхронно извлеченные данные, когда они доступны:

class YourComponent extends React.Component {
  // This function gets called the first time the component is added to the DOM.
  // If the latitude or longitude changes, you'll need to call this function from the componentDidUpdate() lifecycle method.
  componentDidMount () {
    // Obtain atData, probably from props
    const atData = this.props.atData
    getAddressFromLatLong(atData.latitude, atData.longitude)

      // Update the component state with the address
      // setState() will trigger a re-render
      .then(
        address => this.setState({ address: address }),

        // If the Geocode() call fails, this function gets called.
        // As written, this component will continue to show a loading message if Geocode() fails, which isn't great UX.
        // You may want to add the error message to the state and display an error if the Geocode() fails.
        error => console.log('Error retrieving address', error)
      )
  }

  getAddressFromLatLong (lat, long) { 
    return Geocode.fromLatLng(lat, long).then( 
      response => { 
        const address = response.results[0].formatted_address;
        return address; 
      }
    )
  }

  render () {
    // Get atData, probably from props
    const atData = this.props.atData

    // The address is stored in the component state.
    // We'll show a loading message while we're waiting for the data.
    const address = this.state.address

    return ( 
      <tr key={atData.uid}> 
        <td>{atData.uid}</td> 
        <td>{atData.user}</td> 
        <td><TimeStamp time={atData.dateTime} format='full' /></td> 
        <td>{ address || 'Loading address...' }</td> 
      </tr> 
    )
  } 
}

Вы можете улучшить этот пример кода несколькими способами

  • Отображать сообщение об ошибке, если Geocode не удается

  • Визуализация загрузочного счетчика (вместо <tr>) в ожидании завершения Geocode

  • Выполните Geocode из метода componentDidUpdate жизненного цикла, чтобы мы обновляли адрес при каждом изменении широты или долготы
  • Повторите попытку Geocode, если не получится
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...