在React中更改高阶组件中的道具

时间:2018-10-22 14:55:42

标签: javascript reactjs react-native components higher-order-components

我试图了解高阶分量(以下称为HOC):

因此,我创建了一个示例HOC来为我的组件执行GET请求:

import React from 'react';
import { Text } from 'react-native';
import axios from 'axios';

export default (Elem,  props = {}) => {
    // mock props for testing
    props = {
        apiRequests: {
            "todoList": {
                url: "https://jsonplaceholder.typicode.com/todos"
            }
        }
    }
    return class extends React.Component {
        componentWillMount() {
            let apis = Object.keys(props.apiRequests);
            for(let i = 0; i < apis.length; i++) {
                props.apiRequests[apis[i]].done = false
                axios.get(props.apiRequests[apis[i]].url).then((resp) => {
                    console.warn("done")
                    props.apiRequests[apis[i]].done = true
                    props.apiRequests[apis[i]].data = resp.data
                })
            }
        }

        render() {
            return (<Elem {...props} />)
        }
    }
}

现在,当我用上面的HOC包装组件时,我得到了donefalse的道具。

但是,很快,当我收到API响应时,HOC在控制台中记录了done,但是组件中的数据没有更新。我在做什么错了?

1 个答案:

答案 0 :(得分:1)

道具是不可变的。这个

props.apiRequests[apis[i]].done = true

是一个错误,不会导致子组件重新呈现。

从异步请求接收到的状态应存储在组件状态中,setState触发重新渲染。 componentWillMount已被弃用,因为它被用于异步例程。应该是:

return class extends React.Component {
    this.state = {};

    componentDidMount() {
        let apis = Object.keys(props.apiRequests);
        for(let i = 0; i < apis.length; i++) {
            axios.get(props.apiRequests[apis[i]].url).then((resp) => {
                this.setState({ apis[i]]: resp.data });
            })
        }
    }

    render() {
        return (<Elem data={this.state} />)
    }
}

取决于期望如何接收数据,可以使用Promise.all批量执行状态更新。