使用react-hooks在状态更新时执行异步代码

我有类似的东西:

const [loading, setLoading] = useState(false);

...

setLoading(true);

doSomething(); // <--- when here, loading is still false.

设置状态仍然是异步的,那么等待此setLoading()调用完成的最佳方法是什么?

setLoading()似乎并没有接受一个回调像setState()使用。

回答:

基于类

getNextPage = () => {

// This will scroll back to the top, and also trigger the prefetch for the next page on the way up.

goToTop();

if (this.state.pagesSeen.includes(this.state.page + 1)) {

return this.setState({

page: this.state.page + 1,

});

}

if (this.state.prefetchedOrders) {

const allOrders = this.state.orders.concat(this.state.prefetchedOrders);

return this.setState({

orders: allOrders,

page: this.state.page + 1,

pagesSeen: [...this.state.pagesSeen, this.state.page + 1],

prefetchedOrders: null,

});

}

this.setState(

{

isLoading: true,

},

() => {

getOrders({

page: this.state.page + 1,

query: this.state.query,

held: this.state.holdMode,

statuses: filterMap[this.state.filterBy],

})

.then((o) => {

const { orders } = o.data;

const allOrders = this.state.orders.concat(orders);

this.setState({

orders: allOrders,

isLoading: false,

page: this.state.page + 1,

pagesSeen: [...this.state.pagesSeen, this.state.page + 1],

// Just in case we're in the middle of a prefetch.

prefetchedOrders: null,

});

})

.catch(e => console.error(e.message));

},

);

};

转换为基于功能的

  const getNextPage = () => {

// This will scroll back to the top, and also trigger the prefetch for the next page on the way up.

goToTop();

if (pagesSeen.includes(page + 1)) {

return setPage(page + 1);

}

if (prefetchedOrders) {

const allOrders = orders.concat(prefetchedOrders);

setOrders(allOrders);

setPage(page + 1);

setPagesSeen([...pagesSeen, page + 1]);

setPrefetchedOrders(null);

return;

}

setIsLoading(true);

getOrders({

page: page + 1,

query: localQuery,

held: localHoldMode,

statuses: filterMap[filterBy],

})

.then((o) => {

const { orders: fetchedOrders } = o.data;

const allOrders = orders.concat(fetchedOrders);

setOrders(allOrders);

setPage(page + 1);

setPagesSeen([...pagesSeen, page + 1]);

setPrefetchedOrders(null);

setIsLoading(false);

})

.catch(e => console.error(e.message));

};

在上面,我们要顺序运行每个setWhatever调用。这是否意味着我们需要设置许多不同的useEffect挂钩来复制此行为?

回答:

useState状态更新完成后,setter不会提供回调,就像React类组件中的setState一样。为了复制相同的行为,您可以componentDidUpdate通过useEffect使用Hooks

在React类组件中使用类似模式的生命周期方法

useEffect 钩子将第二个参数作为值的数组,在渲染周期完成后,React需要监视这些值以进行更改。

const [loading, setLoading] = useState(false);

...

useEffect(() => {

doSomething(); // This is be executed when `loading` state changes

}, [loading])

setLoading(true);

不同于setStateuseState钩子的更新程序没有回调,但是您始终可以使用a useEffect复制上述行为。但是,您需要确定加载变化

代码的功能方法如下所示

function usePrevious(value) {

const ref = useRef();

useEffect(() => {

ref.current = value;

});

return ref.current;

}


const prevLoading = usePrevious(isLoading);

useEffect(() => {

if (!prevLoading && isLoading) {

getOrders({

page: page + 1,

query: localQuery,

held: localHoldMode,

statuses: filterMap[filterBy],

})

.then((o) => {

const { orders: fetchedOrders } = o.data;

const allOrders = orders.concat(fetchedOrders);

setOrders(allOrders);

setPage(page + 1);

setPagesSeen([...pagesSeen, page + 1]);

setPrefetchedOrders(null);

setIsLoading(false);

})

.catch(e => console.error(e.message));

}

}, [isLoading, preFetchedOrders, orders, page, pagesSeen]);

const getNextPage = () => {

// This will scroll back to the top, and also trigger the prefetch for the next page on the way up.

goToTop();

if (pagesSeen.includes(page + 1)) {

return setPage(page + 1);

}

if (prefetchedOrders) {

const allOrders = orders.concat(prefetchedOrders);

setOrders(allOrders);

setPage(page + 1);

setPagesSeen([...pagesSeen, page + 1]);

setPrefetchedOrders(null);

return;

}

setIsLoading(true);

};

以上是 使用react-hooks在状态更新时执行异步代码 的全部内容, 来源链接: utcz.com/qa/430138.html

回到顶部