javascript - 为什么在异步调用的构造函数中使用 setState 时此组件不更新 - ReactJS/ReactNative?

标签 javascript reactjs react-native constructor setstate

** 已编辑/重新措辞 **

在对我的问题进行了一些很好的回答之后,我编辑了问题中的代码,以尽可能清楚地说明我不理解的内容。

我有一个 withErrorHandler 将用作许多单独组件的 hoc。

其中一个组件是 MyComponent。

withErrorHandler 的 componentWillMount 中的代码按预期工作,但由于它是一个废弃的方法,我必须将它移到某个地方。

位置 - ComponentDidMount 拦截器将无法拦截错误。

位置 - 构造函数 拦截器将拦截错误,但 withError 处理程序中的 Modal 不会显示给用户。

这里到底发生了什么?

import React from 'react';
import Modal from '../../components/UI/Modal/Modal';
import Aux from '../Aux/Aux';

const withErrorHandler = (WrappedComponent, axiosInstance) => {
    return class extends React.Component {
        constructor(props) {
            super(props);
            this.state= {
                error: null
            };
        }
        
        componentWillMount() {
            let { request, response} = axiosInstance.interceptors;
            this.requestInterceptor = request.use(req => {
                this.setState({error: null});
                return req;
            })
            this.responseInterceptor = response.use(resp => resp, error => {
                console.log("axiosInstance Intercepted Error\t",error)
                this.setState({error})
            })
        }

        componentWillUnmount() {
            let { request, response} = axiosInstance.interceptors;
            request.eject(this.requestInterceptor);
            response.eject(this.responseInterceptor);
        }

        errorConfirmedHandler = () => {
            this.setState({error: null})
        }

        render() {
            return <Aux>
                <Modal show={this.state.error} modalClosed={this.errorConfirmedHandler}>
                    {this.state.error ? this.state.error.message : null}
                </Modal>
                <WrappedComponent {...this.props} />
            </Aux>
        }
    }
}

export default withErrorHandler;
import React, { Component } from 'react';
import axiosInstance from '../../AxiosInstance';
import Spinner from '../../components/UI/Spinner/Spinner';
import withErrorHandler from '../../hoc/withErrorHandler/withErrorhandler';

class MyComponent extends Component {

    constructor(props) {
        super(props);
        this.state = {
            ingredients: null,
            error: false
        }
    }

    componentDidMount() {
        // Deliberately placed Error in 'ingredients.json' by removing n
        axiosInstance.get('ingredients.jso').then(response => {
            this.setState({
                ingredients: response.data
            })
        }).catch(error => {
            console.log(`Unable to load Ingredients\nError:\t${JSON.stringify(error, null, 2)}`)
            this.setState({ error: true})
        })
    }

    render() {
        return (
                this.state.ingredients ?
                    <p>show ingredients</p> :
                    this.state.error ? <p>Ingredients Can't be loaded</p> : <Spinner />
        );
    }
}

export default withErrorHandler(MyComponent, axiosInstance);

最佳答案

你不应该在 constructor 中执行任何副作用,它应该主要用于初始化本地状态(和其他变量)或与内容绑定(bind)函数。

其次,在 react 中,您应该谨慎使用以下方法,因为它们在服务器和客户端上都被调用。

  1. 构造函数
  2. componentwillmount(已弃用)
  3. getderivedstatefromprops

更好的方法是在 componentDidMount 生命周期方法中更新状态。该方法会在组件的整个生命周期内触发一次。

class Component1 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      result: null,
    };
    this.fetchResult = this.fetchResult.bind(this)
  }

  componentDidMount() {
    this.fetchResult()
  }

  fetchResult () {
    axiosInstance
      .get(url)
      .then((result) => {
        console.log("result", result);
        this.setState({ result });
      })
      .catch((error) => {});
  }

  render() {
    return (
      <>
        <h1>SomeText</h1>
        <p>{this.state.result ? "Hey, I got the result" : "Waiting..."}</p>
      </>
    );
  }
}

关于javascript - 为什么在异步调用的构造函数中使用 setState 时此组件不更新 - ReactJS/ReactNative?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63425476/

相关文章:

javascript - 如何在 TypeScript 声明源文件中声明嵌套函数?

javascript - componentRecieveProps 获得与渲染中不同的 props 值

javascript - 当键盘在 native 中打开时,如何在 textinput 下面显示组件?

javascript - 如何合并多个文件的命名导出并将其导出为一个对象

javascript - 如何让 Electron + rxdb 工作?

javascript - 禁用 ng repeat 中的按钮

javascript - 在 react 中渲染二维数组的最佳方法?

javascript - 选择 Reactjs 中的 Order Object 键

javascript - Firestore 更新单个字段但创建另一个节点

ios - 如何在 React Native 中使用 UITableViewCellStyleSubtitle 获取原生 UITableView?