如何在React中将状态从孩子传递给父母?

时间:2020-06-08 10:35:22

标签: javascript reactjs

您好,我有一个子组件和一个父组件。在子组件中有一个状态。状态必须在父组件中的className之间切换。我该怎么办?

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)
  }
}

2 个答案:

答案 0 :(得分:0)

状态为1方向

无法将状态传递到树上。在下面的解决方案中,您可能需要绑定功能。您可以通过克隆元素React方法修改孩子的道具。

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)
  }
}

答案 1 :(得分:0)

使用上下文api

您还可以使用上下文api访问树中任何位置的状态。这样,任何有权访问上下文的组件都将在更改时重新呈现,并且数据可以传递和更改到树中的任何点。

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.