具有状态的React HOC中的错误

时间:2018-07-26 12:13:26

标签: javascript reactjs

我根据https://gist.github.com/jesperorb/ad6de7532ade111ae2a7feecc1116339

写了一个试剂鼻

App.js

ModuleA

withToggle.js:

import React, { Component } from "react";
import {withToggle} from './withToggle'

export default class App extends Component {
  render() {
    const ButtonWithToggle = withToggle(<button onClick={()=>{}}>butt</button>);
    return (
      <div className="App">
        <button onClick={()=>{}}>butt</button>
        <ButtonWithToggle />
      </div>
    );
  }
}

结果是,我在控制台中收到一个错误:React.createElement:类型无效-预期为字符串(对于内置组件)或类/函数(对于复合组件),但得到了:对象。在withToggle.js:20上检查代码。 (import React, { Component } from "react"; import PropTypes from 'prop-types'; export const withToggle = (ComposedComponent) => class extends Component { static propTypes = { children: PropTypes.string } state = { toggle: false } onClick = () => { this.setState({ toggle: !this.state.toggle }); } render() { return ( <ComposedComponent {...this.props} onClick={this.onClick}>xxx {this.props.children}</ComposedComponent> ) } }

可能是什么原因?

2 个答案:

答案 0 :(得分:3)

HOC应该应用于 Component ,而不是渲染的组件。
在您的情况下,将withToggle应用于<button onClick={()=>{}}>butt</button>,它是按钮而不是按钮组件的呈现。
另外,您没有正确使用children,而是用onClick覆盖了withToggle提供的onClick={()=>{}}

尝试以下方法:

App.js

import React, { Component } from "react";
import {withToggle} from './withToggle'

const Button = ({onClick, children}) => <button onClick={onClick}>{children}</button>;

export default class App extends Component {
  render() {
    const ButtonWithToggle = withToggle(Button);

    return (
      <div className="App">
        <button onClick={()=>{}}>butt</button>
        <ButtonWithToggle />
      </div>
    );
  }
}

withToggle.js

import React, { Component } from "react";
import PropTypes from 'prop-types';

export const withToggle = (ComposedComponent) =>
    class extends Component {

        static propTypes = {
            children: PropTypes.string
        }

        state = {
            toggle: false
        }

        onClick = () => {
            this.setState(state => ({ toggle: !state.toggle }));
        }

        render() {
            return (
                <ComposedComponent {...this.props} onClick={this.onClick}>{this.props.children}</ComposedComponent>
            )
        }
    }

答案 1 :(得分:0)

我用Toggle.js进行了更改:

import React, { Component } from "react";
import PropTypes from 'prop-types';

export const withToggle = (ComposedComponent) =>
class extends Component {

    static propTypes = {
        children: PropTypes.string.isRequired,
        onClick: PropTypes.func
    }

    static defaultProps = {
        onClick: () => { }
    }

    state = {
        toggle: false
    }
    onClick = () => {
        this.setState({ toggle: !this.state.toggle }, () => console.log('toggle=', this.state.toggle));
        this.props.onClick()
    }

    render() {
        console.log('this.props', this.props)
        return (
            <ComposedComponent {...this.props} onClick={this.onClick}>{this.state.toggle ? 'xxx' : ''}{' '}{this.props.children}</ComposedComponent>
        )
    }
}

但未重新定义onClick,按钮内的文本也未更改(((