用反应调用 API 的最佳实践是啥
Posted
技术标签:
【中文标题】用反应调用 API 的最佳实践是啥【英文标题】:What's the best practice to call API with react用反应调用 API 的最佳实践是什么 【发布时间】:2018-09-19 22:54:20 【问题描述】:在调用 API 时,我实际上在 React 中遇到了一个小问题,因为 ComponentWillMount
已被弃用。
我这样做了:
class MyClass extends Component
constructor()
super();
this.state =
questionsAnswers: [[ answers: [ text: '', id: 0 ], title: '', id: 0 ]],
,
;
componentDidMount()
this.getQuestions();
getQuestions = async () =>
let questionsAnswers = await Subscription.getQuestionsAndAnswers();
questionsAnswers = questionsAnswers.data;
this.setState( questionsAnswers );
;
所以页面在没有questionsAsnwers
的情况下第一次呈现,当我得到questionAnswers
时页面被重新呈现
有没有更好的解决方案来避免重新渲染?
【问题讨论】:
React doc 建议将其加载到 componentDidMount reactjs.org/docs/react-component.html#componentdidmount 还有 github.com/reactjs/reactjs.org/issues/302 在这种情况下,第一次继续加载符号,一旦加载问题,就会改变状态,这将显示问题..也将获得良好的用户体验..更好地使用 redux,它可以让您更好地处理 api 调用和数据绑定 我建议不要对任何 React 组件方法使用async
关键字,因为 Promise 是不可取消的。如果在await
期间卸载了组件,您将对卸载的组件调用this.setState
。这就是为什么创建像Redux 这样的商店的原因; React 组件最好保持完全同步。如果您确实将异步添加到组件,请在 componentDidMount
中创建订阅并在 componentWillUnmount
中取消订阅,但我建议在 React 组件方法中完全避免使用 async
关键字。
如果你的组件第一次渲染的时候没有数据,那么就按照那个来塑造你的组件。见:***.com/questions/49697447/…
【参考方案1】:
根据 react 文档,处理 API 调用的最佳方法是在 componentDidMount
方法 react lifeCycle 中。此时您所能做的就是添加一个微调器以使您的组件更加用户友好。
希望在下一个 React 版本中。 React 将引入一种新的方法来解决这类问题,使用suspense
方法https://medium.com/@baphemot/understanding-react-suspense-1c73b4b0b1e6
【讨论】:
【参考方案2】:使用带有React.Component
的类是componentDidMount
:
class MyComponent extends React.Component
constructor(props)
super(props);
this.state =
error: null,
isLoaded: false,
items: []
;
componentDidMount()
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) =>
this.setState(
isLoaded: true,
items: result.items
);
,
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) =>
this.setState(
isLoaded: true,
error
);
)
render()
const error, isLoaded, items = this.state;
if (error)
return <div>Error: error.message</div>;
else if (!isLoaded)
return <div>Loading...</div>;
else
return (
<ul>
items.map(item => (
<li key=item.id>
item.name item.price
</li>
))
</ul>
);
如果你使用带有 Hooks 的函数组件,你应该这样做:
function MyComponent()
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
// Note: the empty deps array [] means
// this useEffect will run once
// similar to componentDidMount()
useEffect(() =>
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) =>
setIsLoaded(true);
setItems(result);
,
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) =>
setIsLoaded(true);
setError(error);
)
, [])
if (error)
return <div>Error: error.message</div>;
else if (!isLoaded)
return <div>Loading...</div>;
else
return (
<ul>
items.map(item => (
<li key=item.id>
item.name item.price
</li>
))
</ul>
);
示例响应:
"items": [
"id": 1, "name": "Apples", "price": "$2" ,
"id": 2, "name": "Peaches", "price": "$5"
]
来源:
https://reactjs.org/docs/faq-ajax.html
【讨论】:
【参考方案3】:我认为,在这种情况下显示 spinner 是可以的。 您还应该检查 ajax 没有失败。
【讨论】:
以上是关于用反应调用 API 的最佳实践是啥的主要内容,如果未能解决你的问题,请参考以下文章
Swift iOS 应用程序到 REST PHP API - 身份验证的最佳实践是啥?
使用 ML Studio API 开发 CD/CI 的最佳实践是啥?