ReactJS HOC dudes(高阶组件)

时间:2020-02-10 16:55:02

标签: javascript reactjs high-order-component

创建一个更高阶的组件以执行加载程序。 我向自己解释,我有一个执行JSON api获取的组件,但是我希望在加载时不显示卡,这是一条消息,提示正在加载...

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

附加的组件代码及其验证

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 | }

3 个答案:

答案 0 :(得分: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)

             })
        }

答案 1 :(得分:0)

使用Loader作为组件的子代,而不是创建HOC,然后在加载时呈现正在加载的组件,并在完成时呈现常规代码。实施起来容易得多,不需要HOC

答案 2 :(得分:0)

这不是HOC的目的,只需在状态中添加“正在加载”或“正在获取”标志

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;