I write a reagent nose on the basis of https://gist.github.com/jesperorb/ad6de7532ade111ae2a7feecc1116339
App.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>
);
}
}
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({ toggle: !this.state.toggle });
}
render() {
return (
<ComposedComponent {...this.props} onClick={this.onClick}>xxx {this.props.children}</ComposedComponent>
)
}
}
As a result, I get an error in the console: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. Check your code at withToggle.js:20. (Where <ComposedComponent
)
What could be the reason?
HOC should be applied on a Component and not a rendered component.
On your case withToggle
is applied on <button onClick={()=>{}}>butt</button>
, which is a rendering of a button and not a button component.
Also, you're not using children
right and you're overriding the onClick
provided from withToggle
with onClick={()=>{}}
.
Try this instead:
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>
)
}
}
I change withToggle.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>
)
}
}
but onClick is not redefined and the text inside the button does not change((
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.