最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using a HOC (higher order component) with React-Redux connect - Stack Overflow

programmeradmin5浏览0评论

I'm trying to get more fortable with using higher order ponents so I'm working on refactoring an application. I have four different ponents that all reuse the same fetchData request, as well as error/loading conditionals. My plan is to take this reusable data and put it into a HOC. I've tried many different examples from StackOverflow, Reddit, Github, etc and none of them are working in my specific case.

Here's my HOC:

const WithDataRendering = WrappedComponent => props => {
class WithDataRenderingComponent extends Component {
    ponentDidMount() {
    this.props.fetchData(url)
    }
    render() {
    if (this.props.hasErrored) {
        return (
        <p>
            Sorry! There was an error loading the items:{" "}
            {this.props.hasErrored.message}
        </p>
        )
    }

    if (this.props.isLoading) {
        return (
        <div>
            <Skeleton count={10} />
        </div>
        )
    }

    return <WrappedComponent {...this.props} />
    }
}
const mapStateToProps = state => {
    return {
    data: state.data,
    hasErrored: state.dataHasErrored,
    isLoading: state.dataIsLoading
    }
}

const mapDispatchToProps = dispatch => {
    return {
    fetchData: url => dispatch(fetchData(url))
    }
}
return connect(mapStateToProps, mapDispatchToProps)(
    WithDataRenderingComponent
)
}

export default WithDataRendering

And here's a ponent that I'm trying to wrap with the HOC:

export class AllData extends Component<Props> {
    render() {
        return (
        ...
        )
    }
}

const mapStateToProps = state => {
    return {
        data: state.data,
        hasErrored: state.dataHasErrored,
        isLoading: state.dataIsLoading
    }
}

const mapDispatchToProps = dispatch => {
    return {
        fetchData: url => dispatch(fetchData(url))
    }
}

export default pose(
    connect(mapStateToProps, mapDispatchToProps),
    WithDataRendering(AllData)
)

I get three errors in the console:

Warning: Component(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

invariant.js:42 Uncaught Error: Component(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

ReactDOMComponentTree.js:111 Uncaught TypeError: Cannot read property '__reactInternalInstance$24sdkzrlvvz' of null

A couple other techniques I tried are in this SO post and this gist. I've tried using pose and not using it, doesn't matter. I'm really at a loss here. Any ideas why this HOC isn't rendering properly?

Also, I'm not opposed to using render props as a solution if that fits better. I need to get more practice with both methods.

I'm trying to get more fortable with using higher order ponents so I'm working on refactoring an application. I have four different ponents that all reuse the same fetchData request, as well as error/loading conditionals. My plan is to take this reusable data and put it into a HOC. I've tried many different examples from StackOverflow, Reddit, Github, etc and none of them are working in my specific case.

Here's my HOC:

const WithDataRendering = WrappedComponent => props => {
class WithDataRenderingComponent extends Component {
    ponentDidMount() {
    this.props.fetchData(url)
    }
    render() {
    if (this.props.hasErrored) {
        return (
        <p>
            Sorry! There was an error loading the items:{" "}
            {this.props.hasErrored.message}
        </p>
        )
    }

    if (this.props.isLoading) {
        return (
        <div>
            <Skeleton count={10} />
        </div>
        )
    }

    return <WrappedComponent {...this.props} />
    }
}
const mapStateToProps = state => {
    return {
    data: state.data,
    hasErrored: state.dataHasErrored,
    isLoading: state.dataIsLoading
    }
}

const mapDispatchToProps = dispatch => {
    return {
    fetchData: url => dispatch(fetchData(url))
    }
}
return connect(mapStateToProps, mapDispatchToProps)(
    WithDataRenderingComponent
)
}

export default WithDataRendering

And here's a ponent that I'm trying to wrap with the HOC:

export class AllData extends Component<Props> {
    render() {
        return (
        ...
        )
    }
}

const mapStateToProps = state => {
    return {
        data: state.data,
        hasErrored: state.dataHasErrored,
        isLoading: state.dataIsLoading
    }
}

const mapDispatchToProps = dispatch => {
    return {
        fetchData: url => dispatch(fetchData(url))
    }
}

export default pose(
    connect(mapStateToProps, mapDispatchToProps),
    WithDataRendering(AllData)
)

I get three errors in the console:

Warning: Component(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

invariant.js:42 Uncaught Error: Component(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

ReactDOMComponentTree.js:111 Uncaught TypeError: Cannot read property '__reactInternalInstance$24sdkzrlvvz' of null

A couple other techniques I tried are in this SO post and this gist. I've tried using pose and not using it, doesn't matter. I'm really at a loss here. Any ideas why this HOC isn't rendering properly?

Also, I'm not opposed to using render props as a solution if that fits better. I need to get more practice with both methods.

Share Improve this question edited Apr 4, 2018 at 22:02 wildlifehexagon asked Apr 4, 2018 at 21:53 wildlifehexagonwildlifehexagon 5236 silver badges27 bronze badges 6
  • First thing I notice is that your HOC exports WithGoDataRendering which isn't defined anywhere (did you mean WithDataRendering?) – hbauer Commented Apr 4, 2018 at 22:01
  • Sorry, that was a typo while I was modifying my code. I've corrected it to reflect the proper names – wildlifehexagon Commented Apr 4, 2018 at 22:03
  • You'll want to drop the props => argument to WithDataRendering, and you currently connect both in the HOC and in the pose application (although that probably won't cause any errors). Just briefly glanced over the code though, so there might be some other issues. – Oblosys Commented Apr 5, 2018 at 0:04
  • You're right, props => was the main issue. Will post more details later. Thank you. – wildlifehexagon Commented Apr 5, 2018 at 21:22
  • Apologies for the off-topic question but what does this mean: export class AllData extends Component<Props> {? I am referring to the '<Props> alongside Component syntax. – Kayote Commented Jul 23, 2018 at 15:13
 |  Show 1 more ment

1 Answer 1

Reset to default 6

I was able to fix this by dropping the props => argument as Oblosys suggested. I also reconfigured the export statement in AllData to be:

export default connect(mapStateToProps, mapDispatchToProps)(WithDataRendering(AllData))

since I didn't really need to use pose there.

发布评论

评论列表(0)

  1. 暂无评论