0

I checked other questions and also docs but I cannot make it work. I want to pass a handler function to a child component within its props to change between themes.

I defined a state in the parent component and the handler that sets the new state. I tried with and without a parameter.

This is the parent

class MyApp extends App {

  constructor(props) {
    super(props);
    this.state = {
      colorScheme: "light"
    };
    this.handleColorScheme = this.handleColorScheme.bind(this);
  }

  handleColorScheme = scheme => {
    this.setState({ colorScheme: scheme });
  };

  render() {
    const { Component, pageProps } = this.props;

    const props = {
      ...pageProps,
      schemeHandler: this.handleColorScheme
    };
    return (
      <Container>
         <ThemeProvider
            theme={this.state.colorScheme === "light" ? theme : themeDark}
          >
            <Component {...props} />
          </ThemeProvider>
      </Container>
    );
  }
}

export default MyApp;

And this the child component

export default function Layout(props) {
  const [theme, setTheme] = useState({
    palette: {
      type: "light"
    }
  });

  const toggleDarkTheme = () => {
    let newPaletteType = theme.palette.type === "light" ? "dark" : "light";    
    props.schemeHandler(newPaletteType);
  };

  return (
   <div>
      <CssBaseline />
      <div className={classes.root}>
        <AppBar
          position="absolute"
          color={"default"}
          className={classes.appBar}
        >
          <Toolbar>
              <IconButton onClick={toggleDarkTheme}>
                <Dark />
              </IconButton>            
          </Toolbar>
        </AppBar>
        <main className={classes.content}>          
          {props.children}
        </main>
      </div>
    </div>
  );
}

When I click the button it says that toggleDarkTheme is not a function. Debugging with dev tools I see that I never reach parent function. How can this function be passed in props?

3
  • Can you verify that toggleDarkTheme actually triggers anything? Just comment out the current logic in that function and do an alert or console.log() Commented Aug 15, 2019 at 9:14
  • @ChristopherNgo yes, it triggers toggleDarkTheme function in the child component Commented Aug 15, 2019 at 9:19
  • Can you add a Code Sandbox link: codesandbox.io/s/new Commented Aug 15, 2019 at 9:55

2 Answers 2

2
  1. You should not use state in both parent and children, it makes your logic become complicated. You can place the state in parent and pass the modifier function as prop to children (children become dumb component).

  2. No need to bind the modifier function.

  3. Parent component can become a function instead of a class.

Example: https://codesandbox.io/embed/passing-react-func-as-props-kf8lr

Sign up to request clarification or add additional context in comments.

1 Comment

Finally get it working, there was a another component between app.js and Layout that was not passing down props. Found it debugging the props. Anyway I followed your advice, now logic is simplified, only parent holds the state
0

I suspect it is because of syntax.

<IconButton onClick={() => toggleDarkTheme() }>

Changing this line in your child component should do the trick. Cant really know without having some minimal code to test run

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.