MST

星途 面试题库

面试题:在React组件加载阶段处理异步数据获取

假设你正在开发一个React组件,需要在组件加载阶段从API获取数据。请说明如何正确地在组件加载阶段的生命周期方法中处理异步数据获取,以避免潜在的性能问题和数据不一致问题。如果在`componentDidMount`中发起异步请求,如何确保在组件卸载时取消未完成的请求?
26.7万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试
  1. 在组件加载阶段处理异步数据获取
    • 使用async/awaittry/catch: 在componentDidMount生命周期方法中,可以使用async/await语法来处理异步操作,同时使用try/catch捕获可能出现的错误。例如:
import React, { Component } from'react';

class MyComponent extends Component {
    state = {
        data: null,
        error: null
    };

    async componentDidMount() {
        try {
            const response = await fetch('your - api - url');
            const result = await response.json();
            this.setState({ data: result });
        } catch (error) {
            this.setState({ error });
        }
    }

    render() {
        const { data, error } = this.state;
        if (error) {
            return <div>Error: {error.message}</div>;
        }
        if (!data) {
            return <div>Loading...</div>;
        }
        return <div>{JSON.stringify(data)}</div>;
    }
}

export default MyComponent;
  • 使用Promise: 也可以直接使用Promise.then().catch()方法来处理异步操作。例如:
import React, { Component } from'react';

class MyComponent extends Component {
    state = {
        data: null,
        error: null
    };

    componentDidMount() {
        fetch('your - api - url')
          .then(response => response.json())
          .then(result => this.setState({ data: result }))
          .catch(error => this.setState({ error }));
    }

    render() {
        const { data, error } = this.state;
        if (error) {
            return <div>Error: {error.message}</div>;
        }
        if (!data) {
            return <div>Loading...</div>;
        }
        return <div>{JSON.stringify(data)}</div>;
    }
}

export default MyComponent;
  1. 在组件卸载时取消未完成的请求
    • 使用AbortController(现代浏览器支持)
import React, { Component } from'react';

class MyComponent extends Component {
    state = {
        data: null,
        error: null
    };
    controller = new AbortController();

    async componentDidMount() {
        const { signal } = this.controller;
        try {
            const response = await fetch('your - api - url', { signal });
            const result = await response.json();
            this.setState({ data: result });
        } catch (error) {
            if (error.name === 'AbortError') {
                // 这是因为组件卸载导致的请求取消,不视为错误
                return;
            }
            this.setState({ error });
        }
    }

    componentWillUnmount() {
        this.controller.abort();
    }

    render() {
        const { data, error } = this.state;
        if (error) {
            return <div>Error: {error.message}</div>;
        }
        if (!data) {
            return <div>Loading...</div>;
        }
        return <div>{JSON.stringify(data)}</div>;
    }
}

export default MyComponent;
  • 对于不支持AbortController的环境: 可以使用第三方库,如axios,它自身支持取消请求。例如:
import React, { Component } from'react';
import axios from 'axios';

class MyComponent extends Component {
    state = {
        data: null,
        error: null
    };
    cancelToken = axios.CancelToken.source();

    async componentDidMount() {
        try {
            const response = await axios.get('your - api - url', { cancelToken: this.cancelToken.token });
            this.setState({ data: response.data });
        } catch (error) {
            if (axios.isCancel(error)) {
                // 这是因为组件卸载导致的请求取消,不视为错误
                return;
            }
            this.setState({ error });
        }
    }

    componentWillUnmount() {
        this.cancelToken.cancel('Component is unmounting');
    }

    render() {
        const { data, error } = this.state;
        if (error) {
            return <div>Error: {error.message}</div>;
        }
        if (!data) {
            return <div>Loading...</div>;
        }
        return <div>{JSON.stringify(data)}</div>;
    }
}

export default MyComponent;