如何在执行 render 方法之前使用 promise 为状态赋值
How to assign a value to the state with a promise prior to the render method executing
编辑:
Here is a working jsComplete(使用 chrome)我将 JSON 分配给状态而不是进行 api 调用。不过,我正在尝试对 api 调用做同样的事情。
如何在 render()
方法运行之前将值赋给状态 属性 locoData
?
locoData
永远不会被分配,并且 console.log(resp.data);
在 render 方法之后执行。我是 React 的新手,只是想了解 JavaScript 中的新功能,例如 promises,这让我很困惑。我在 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"}
我不知道这是否是您问题的正确答案。
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
}
即组件挂载前运行。
第二种解决方案是使用 react hooks 的新特性,在这种情况下,与 componentWillMount
相同
useEffect(() => {
return () => {
//here you can set your state
}
}, [])
PS: 只需使用钩子,旧的反应循环已弃用
您需要使用条件渲染,将一个变量设置为 true,例如 state = { isLoading: true }
一旦您从 api 接收到数据,就将其设置为 false。
conditional rendering tutorial
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>
);
}
}
编辑:
Here is a working jsComplete(使用 chrome)我将 JSON 分配给状态而不是进行 api 调用。不过,我正在尝试对 api 调用做同样的事情。
如何在 render()
方法运行之前将值赋给状态 属性 locoData
?
locoData
永远不会被分配,并且 console.log(resp.data);
在 render 方法之后执行。我是 React 的新手,只是想了解 JavaScript 中的新功能,例如 promises,这让我很困惑。我在 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"}
我不知道这是否是您问题的正确答案。 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
}
即组件挂载前运行。 第二种解决方案是使用 react hooks 的新特性,在这种情况下,与 componentWillMount
相同useEffect(() => {
return () => {
//here you can set your state
}
}, [])
PS: 只需使用钩子,旧的反应循环已弃用
您需要使用条件渲染,将一个变量设置为 true,例如 state = { isLoading: true }
一旦您从 api 接收到数据,就将其设置为 false。
conditional rendering tutorial
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>
);
}
}