Как присвоить значение состоянию с обещанием до выполнения метода рендеринга - PullRequest
0 голосов
/ 04 мая 2019

EDIT:

Вот рабочий jsComplete (используйте chrome), в котором я назначаю JSON состоянию, а не выполняю вызов API. Я пытаюсь сделать то же самое с помощью вызова API.

Как присвоить значение свойству состояния locoData до запуска метода render()?

locoData никогда не назначается, а console.log(resp.data); выполняется после метода рендеринга. Я новичок, чтобы реагировать, и просто догонять новые функции в JavaScript, такие как обещания, и это действительно смущает меня. Я выполняю этот код в jsComplete

Если я назначаю JSON состоянию вместо попытки использовать метод axios.get, он работает нормально. Ответ JSON находится внизу.

Я удалил ключ карты Bing.

  const LocationData = (props) => (
    <div>
      {props.location => <Location key={location.traceId} {...location}/>}
    </div>
)

class Location extends React.Component {    
    state = { locoData: {} },   
    const a = axios.get("https://dev.virtualearth.net/REST/v1/Locations?CountryRegion=US&adminDistrict=WA&locality=Somewhere&postalCode=98001&addressLine=100%20Main%20St.&key=bingMapKey").then(resp => { 
      console.log(resp.data);
      this.setState({ locoData: resp.data });  
    });

  render() {     
    resources = this.state.locoData.resourceSets[0].resources.map(function(resource){      
      return <div className="resource" key={resource.name} {...resource}></div>;
    });
    return (
        <div>
          <img src={location.brandLogoUri} />
        <div>
          <div>{resources.name}</div>
          <div>{resources[0].props.point.coordinates[0]} {resources[0].props.point.coordinates[1]}</div>
        </div>
        </div>
    );
  }
}

class App extends React.Component {
  state = {
    location: [],
  };
  displayLocation = (locationData) => {
    this.setState(prevState => ({
        location: [...prevState.location, locationData],
    }));
  };
    render() {
    return (
        <div>
          <div>{this.props.title}</div>
        <Location LocationData={this.state.location} />
        </div>
    );
  } 
}

ReactDOM.render(
    <App title="Simple Weather App" />,
  mountNode,
);

{"authenticationResultCode":"ValidCredentials","brandLogoUri":"http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png","copyright":"Copyright © 2019 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.","resourceSets":[{"estimatedTotal":1,"resources":[{"__type":"Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1","bbox":[47.275809008582883,-122.25881456692279,47.283534443724236,-122.24363249293789],"name":"100 Main St, Algona, WA 98001","point":{"type":"Point","coordinates":[47.279671726153559,-122.25122352993034]},"address":{"addressLine":"100 Main St","adminDistrict":"WA","adminDistrict2":"King County","countryRegion":"United States","formattedAddress":"100 Main St, Algona, WA 98001","locality":"Algona","postalCode":"98001"},"confidence":"High","entityType":"Address","geocodePoints":[{"type":"Point","coordinates":[47.279671726153559,-122.25122352993034],"calculationMethod":"InterpolationOffset","usageTypes":["Display"]},{"type":"Point","coordinates":[47.279653371643015,-122.25128403728938],"calculationMethod":"Interpolation","usageTypes":["Route"]}],"matchCodes":["Good"]}]}],"statusCode":200,"statusDescription":"OK","traceId":"591320e018b0476cbbe71f338ecab555|BN1EAE8F4E|7.7.0.0|Ref A: 3983F574345D41A782020BC15BA6BF08 Ref B: BN3EDGE0210 Ref C: 2019-05-04T04:30:29Z"}

Ответы [ 2 ]

1 голос
/ 04 мая 2019

Вам необходимо использовать условный рендеринг, для переменной установите значение true, например state = { isLoading: true }. Как только вы получите данные от API, вы установите для этого значения значение false.

учебник условного рендеринга

class Location extends React.Component {
  state = { locoData: {}, isLoading: true, errorMessage: "" };

  getDataFromApi = () => {
    const t_his = this;
    const a = axios
      .get(
        "https://dev.virtualearth.net/REST/v1/Locations?CountryRegion=US&adminDistrict=WA&locality=Somewhere&postalCode=98001&addressLine=100%20Main%20St.&key=bingMapKey"
      )
      .then(resp => {
        console.log(resp.data);
        t_his.setState({ locoData: resp.data, isLoading: false });
      })
      .catch(function(error) {
        t_his.setState({
          errorMessage: "Error occured with status: " + error.response.status,
          isLoading: false
        });
      });
  };

  componentDidMount = () => {
    this.getDataFromApi();
  };

  render() {

    const resourcesData =
      (this.state.locoData &&
        this.state.locoData.resourceSets &&
        this.state.locoData.resourceSets[0].resources) ||
      [];

    const resources = resourcesData.map(function(resource) {
      return <div className="resource" key={resource.name} {...resource} />;
    });

    const name = (resources && resources[0] && resources[0].props.name) || "";
    const coordinates =
      (resources && resources[0] && resources[0].props.point.coordinates[0]) ||
      "";
    const coordinates1 =
      (resources && resources[0] && resources[0].props.point.coordinates[1]) ||
      "";

    return (
      <div>
        {this.state.isLoading ? (
          <Loader type="Puff" color="#00BFFF" height="100" width="100" />
        ) : (
          <div>
            {!!this.state.errorMessage ? (
              <h2>{this.state.errorMessage}</h2>
            ) : (
              <div>
                <img src={this.state.locoData.brandLogoUri} />
                <div>
                  <div>{name}</div>
                  <div>
                    {coordinates} {coordinates1}
                  </div>
                </div>
              </div>
            )}
          </div>
        )}
      </div>
    );
  }
}

Демо

1 голос
/ 04 мая 2019

Я не знаю, правильный ли это ответ на вашу проблему.У React есть цикл рендеринга, который вы можете найти здесь:

https://reactjs.org/docs/react-component.html?utm_source=caibaojian.com
или
https://reactjs.org/docs/state-and-lifecycle.html

Это можно сделать двумя способами: первый использует функцию

 componentWillMount(){
    //Here you can set state normally
    }

, который запускается до монтирования компонента.Второе решение заключается в использовании новой функции ловушек реагирования, которая в данном случае аналогична componentWillMount

useEffect(() => {
  return () => {
    //here you can set your state
  }
}, [])

PS: Просто используйте ловушки, старая реакцияцикл устарел

...