是的,有一个类似的(但不一样!)用钩子代替componentDidMount
,这是useEffect
钩子.
其他答案并不能真正回答您关于在哪里可以进行API调用的问题.您可以使用useEffect
和passing in an empty array or object as the second argument代替componentDidMount()
来进行API调用.这里的关键是第二个论点.如果不提供空数组或对象作为第二个参数,则会在每次渲染时调用API调用,它实际上会变成一个componentDidUpdate
.
如文件所述:
传入输入的空数组[]告诉React,您的效果不依赖于组件中的任何值,因此效果将仅在装载时运行,在卸载时清除;它不会在更新时运行.
以下是一些需要进行API调用的场景示例:
API调用严格在Mount上进行
try 运行下面的代码并查看结果.
function User() {
const [firstName, setFirstName] = React.useState(null);
const [lastName, setLastName] = React.useState(null);
React.useEffect(() => {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
const {name} = data.results[0];
setFirstName(name.first);
setLastName(name.last);
});
}, []); // <-- Have to pass in [] here!
return (
<div>
Name: {!firstName || !lastName ? 'Loading...' : `${firstName} ${lastName}`}
</div>
);
}
ReactDOM.render(<User />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
每当某些属性/状态发生变化时调用API
例如,如果您正在显示一个用户的配置文件页面,其中每个页面都有一个userID state/prop,那么您应该将该ID作为一个值传递到第二个参数useEffect
中,以便为新的用户ID重新提取数据.componentDidMount
在这里是不够的,因为如果您直接从用户a转到用户B的配置文件,组件可能不需要重新安装.
按照传统的上课方式,你会做:
componentDidMount() {
this.fetchData();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.id !== this.state.id) {
this.fetchData();
}
}
有了钩子,那就是:
useEffect(() => {
this.fetchData();
}, [id]);
try 运行下面的代码并查看结果. Change the id to 2 for instance to see that useEffect
is run again.
function Todo() {
const [todo, setTodo] = React.useState(null);
const [id, setId] = React.useState(1);
React.useEffect(() => {
if (id == null || id === '') {
return;
}
fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
.then(results => results.json())
.then(data => {
setTodo(data);
});
}, [id]); // useEffect will trigger whenever id is different.
return (
<div>
<input value={id} onChange={e => setId(e.target.value)}/>
<br/>
<pre>{JSON.stringify(todo, null, 2)}</pre>
</div>
);
}
ReactDOM.render(<Todo />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.8.1/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.8.1/umd/react-dom.development.js"></script>
<div id="app"></div>
你应该仔细阅读useEffect
,以便知道你能/不能用它做什么.
担心
正如丹·阿布拉莫夫在this GitHub Issue年前所说:
从长远来看,我们将不鼓励这种(使用效应)模式,因为它鼓励比赛条件.比如——在通话开始和结束之间,任何事情都可能发生,你可能会得到新的props .相反,我们建议暂挂数据获取
所以请继续关注悬念!