开发者问题收集

ReactJS HOC 兄弟 (高阶组件)

2020-02-10
437

创建一个更高阶的组件,以便能够执行加载器。 我解释一下,我有一个组件,它执行对 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 中的变量“courses”。能够将消息加载的逻辑放在 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个回答

你可以这样做

    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)

             })
        }
Denis Kuratovich
2020-02-10

无需创建 HOC,而是使用 Loader 作为组件的子项,然后在加载时渲染加载组件,并在加载完成后渲染正常代码。实现起来更容易,并且不需要 HOC

Sodnarts
2020-02-10

这不是 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;
Rubén Morales Félix
2020-02-10