Gal Grünfeld
Gal Grünfeld

Reputation: 840

How to pass states here?

I have a component ModifyWordPartButton that has a state isHovered and a child IconButton. IconButton onclick that is a child of another component, SelectWordPartToModify, that has a method handleClickOpen(). IconButton is supposed to be able to have its onClick = SelectWordPartToModify's handleClickOpen().

When using this code:

ModifyWordPartButton:

.
.
.
render() {
  return (
    <div>
      <IconButton className={this.state.isHovered ? 'hoveredClass' : null />
    </div>
  );
}

SelectWordPartToModify:

.
.
.
render() {
    <ModifyWordPartButton />
}

results in IconButton inheritng ModifyWordPartButton's isHovered state but not inheriting SelectWordPartToModify's handleClickOpen().

And when I use this code: ModifyWordPartButton:

.
.
.
render() {
  return (
    <div>
      {this.children}
    </div>
  );
}

SelectWordPartToModify:

.
.
.
render() {
  <ModifyWordPartButton onClick={this.handleClickOpen}>
    <IconButton onClick={this.handleClickOpen}
  </ModifyWordPartButton
}

IconButton doesn't inherit ModifyWordPartButton's isHovered state.

I tried in ModifyWordPartButton's render() to replace this.props.children with:

this.props.children.map(
  child => {
    React.cloneElement(child, this.state)
  }
)

but React gave me an error about not recognizing IconButton's isHovered property.

Here's the full code I use: https://codesandbox.io/s/zwlz41mo93?codemirror=1&eslint=1&fontsize=14

How can I solve this?

Upvotes: 0

Views: 93

Answers (1)

Jolly
Jolly

Reputation: 1768

Sorry, I don't fully understand your question, but.. Can't you pass more than one props to IconButton? Something like the following:

SelectWordPartToModify

render() {
    return <ModifyWordPart handleClick={this.handleClickOpen} />
}

ModifyWordPart

render() {
    return (
        <IconButton
            className={this.state.isHovered ? 'hoveredClass' : null}
            handleClick={this.props.handleClick} />
    );
}

This way, handleClickOpen must be defined in SelectWordPartToModify, and can be executed inside IconButton using this.props.handleClick(). Moreover, you also have the className of IconButton based on the isHovered property of ModifyTwoPart


EDIT: Regarding your sandbox:

  1. At line 78 of ModifyWordPartButton you should not write handleClickOpen={this.handleClickOpen} but instead onClick={this.handleClickOpen}: being a div a simple DOM element, you cannot pass to it property like a your own Component.

  2. At line 71 of the same file, again, you should use onClick instead of handleClickOpen: IconButton is indeed a Component, but it belongs with Material UI and it seems to expect an onClick props.

  3. Moreover, in both lines you should not write this.handleClickOpen, but instead this.props.handleClickOpen, because the function is passed to ModifyWordPartButton using the props!

  4. I guess the IconButton at line 60-68 of SelectSuffixToModify can be deleted without any ripercussion (if I guest right what you wanted to do, then it is not useful at all keeping it there).

I've forked your sandCodebox, here it goes → https://codesandbox.io/s/6wxj4nyn6z I think it does what you asked for.

Though, I think you need some clarification because, based on what you wrote, I think you have some confusion in your mind. When you write your own Component, you can make them expecting the props you want: in your example, ModifyWordPartButton is your own Component and you created him in a way that expect a prop named handleClickOpen; thus, when you call it from the SelectSuffixToModify render() method, you can pass it a function using handleClickOpen={...}.

Instead, IconButton is made from someone else, thus you should be aware of what are its props! Information which I guess you can find it on the official documentation of material UI :)

Upvotes: 1

Related Questions