Изменить реквизит в компоненте высшего порядка в реакции - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь понять компоненты высшего порядка (именуемые ниже 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, я получаю реквизиты с done как false.

Однако вскоре, когда я получаю свой ответ API, HOC регистрирует done в моей консоли, но данные в моем компоненте не обновляются.Что я делаю не так?

1 Ответ

0 голосов
/ 22 октября 2018

Реквизит являются неизменными.Это

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.

...