简体   繁体   中英

How to pass a state from a child to a parent in React?

Hello i have a child component and a parent component. In the child component there is a state. The state has to toggle between classNames in the parent component. How can i do that?

 export function Parent({ children, darkMode }) { return ( <div className={cx(styles.component, darkMode && styles.darkMode)}> { children } </div> ) } export function Child() { const [darkMode, setDarkMode] = React.useState(false) return ( <header> <div className={styles.component}> <div className={styles.content}> <button onClick={colorSwith} className={styles.toggle}>Toggle</button> </div> </div> </header> ) function colorSwith() { setDarkMode(true) } }

With state it's 1 directional

It's not possible to pass state up the tree. In the solution below you might need to bind the function. You can mod props of children via the clone element React method.

export function Parent({ children, darkMode }) {
  const [darkMode, setDarkMode] = React.useState(false)
  return (
    <div className={cx(styles.component, darkMode && styles.darkMode)}>
      {React.cloneElement(children, { setDarkMode })}
    </div>
  )
}

export function Child(props) {
  return (
    <header>
      <div className={styles.component}>
        <div className={styles.content}>
          <button onClick={colorSwith} className={styles.toggle}>Toggle</button>
        </div>
      </div>
    </header>
  )
  function colorSwith() {
    props.setDarkMode(true)
  }
}

Use the context api

You can also use the context api to access state anywhere in the tree. This way any component that has access to the context will rerender on change and data is passable and changable to any point in the tree.

Check out this example from the react docs

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
} 

See how the context is set on the `App` level with a `Provider` and then changed in the `ThemeButton` with the `useContext` hook. This is a simple use case that seems simmilar to yours.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM