-1

创建一个高阶组件以能够执行加载程序。我解释一下自己,我有一个组件可以执行对 JSON api 的获取,但是我希望在加载并且卡片没有出现时,这是一条消息,上面写着 Loading ...

我已经在卡片组件中进行了此验证,但我希望它是动态的,并且也能够在用户卡片中重复此逻辑

附加组件代码及其验证

import React, { Component } from 'react';
import Axios from 'axios';
import Cards from '../Molecules/Cards';
import whithLoader from "../HOC/whitLoeader"

class Axios_cards extends Component {

    constructor(props) {

        super(props)
        this.state = {
            courses : []
        }      
    }
//                              FIX ME

    componentDidMount() {
        Axios.get('https://my-json-server.typicode.com/jee4nc/myjsonserver/lista')
        .then(response => this.setState({
                courses: response.data

        }))
    }
    render() {

        const { courses } = this.state
        return (
            <>

            <div className="ed-grid m-grid-3">

            {courses.length===0 ?
                <h1>Cargando...</h1> :
                courses.map(u =>        //Validation for Loading message
                                <Cards
                                key={u.id}
                                title={u.title}
                                description={u.description}
                                image={u.image}
                                email={u.email}
                                price={u.price}
                                />)

            }
            </div>
            </>
        )
    }
}

export default whithLoader(Axios_cards);

高阶组件:

import React, { Component } from 'react'; //Se tiene que importar React

const withLoader = (WrappedComponent) => { //Esto se tiene que crear de esta maneraa
    return class whithLoader extends Component{
        constructor(props) { //Se tiene que crear un metodo constructor que reciba las props
            super(props)
        }
        render() {
            console.log(this.props);
            return <WrappedComponent {...this.props} />
        }
    }
}
export default withLoader;

这就是为什么我需要能够访问 CardsGrid 中的变量“课程”。为了能够将消息加载的逻辑放在 HOC 内部

我试试这个:

const withLoader = (WrappedComponent) => { //Esto se tiene que crear de esta maneraa
    return class whithLoader extends Component{
        constructor(props) { //Se tiene que crear un metodo constructor que reciba las props
            super(props)
        }
        render() { 
            //I want to get the length of the array, so that when it is being requested and 0 is 
           //displayed Loading ...
            return this.props.courses.length === 0 ? <h1>Loading...</h1> : <WrappedComponent {...this.props} />
        }
    }
}

但是...:消息错误

TypeError: Cannot read property 'length' of undefined
whithLoader.render
src/Components/HOC/whitLoeader.js:10
   7 |         }
   8 |         render() {
   9 |             
> 10 |             return this.props.courses.length === 0 ? <h1>Loading...</h1> : <WrappedComponent {...this.props} />
  11 |         }
  12 |     }
  13 | }
4

3 回答 3

1

你可以这样做

    const withLoader = (WrappedComponent) => { //Esto se tiene que crear de esta maneraa
    return class whithLoader extends Component{
        constructor(props) { //Se tiene que crear un metodo constructor que reciba las props
            super(props)
            this.state = {
                loading: false
            }  
        }
        render() { 
            //I want to get the length of the array, so that when it is being requested and 0 is 
           //displayed Loading ...
            return this.state.loading ? <h1>Loading...</h1> : <WrappedComponent {...this.props} setLoading={loading => this.setState({loading})} />
        }
    }
}

组件接收 setLoading 作为prop,只需将其添加到:

    componentDidMount() {
            this.props.setLoading(true)
            Axios.get('https://my-json-server.typicode.com/jee4nc/myjsonserver/lista')
            .then(response => {
                     this.setState({ courses: response.data })
                     this.props.setLoading(false)

             })
        }
于 2020-02-10T17:20:42.077 回答
0

Instead of creating a HOC, use the Loader as a child of the component, then while loading, render the loading component, and when its done, render the normal code. Much easier to implement, and no need for a HOC

于 2020-02-10T17:09:48.970 回答
0

这不是 HOC 的目的,只是在状态中添加一个 'loading' 或 'fetching' 标志

import React, { Component } from 'react';
import Axios from 'axios';
import Cards from '../Molecules/Cards';

class Axios_cards extends Component {

    constructor(props) {
        super(props)
        this.state = {
            courses : [],
            loading: true
        }      
    }
    componentDidMount() {
        this.axiosCancelSource = axios.CancelToken.source();
        Axios.get('https://my-json-server.typicode.com/jee4nc/myjsonserver/lista', { cancelToken: this.axiosCancelSource.token })
            .then(response => this.setState({
                courses: response.data,
                loading: false
            })).catch(() => this.setState({
                loading: false
            }))
    }
    componentWillUnmount () {
        this.axiosCancelSource.cancel('Component unmounted.')
    }
    render() {
        const { loading, courses } = this.state
        return (
            <>
            <div className="ed-grid m-grid-3">
                { loading ?
                    <h1>Cargando...</h1> :
                    courses.map(u =>        //Validation for Loading message
                                <Cards
                                    key={u.id}
                                    title={u.title}
                                    description={u.description}
                                    image={u.image}
                                    email={u.email}
                                    price={u.price}
                                />)

                }
                </div>
            </>
        )
    }
}

export default Axios_cards;
于 2020-02-10T17:21:19.623 回答