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