如何在 ReactJS 中的子组件(兄弟组件)之间共享状态?

IT技术 javascript reactjs gatsby
2021-05-11 07:16:30

我想将状态传递给兄弟姐妹甚至祖父母。

我有 3 个组件。在里面Header,我有一个带有 onClick 功能的按钮,可以在里面切换下拉菜单Navigation顺便说一句,我想将相同的状态传递给AnotherComponent.

如何isDropdownOpenedHeadertoNavigation传递状态(例如AnotherComponent

<div>
     <Header />
       <Navigation />
        <div>
          <div>
             <div>
               <AnotherComponent />
             </div>
           </div>
        </div>
</div>
4个回答

这就是为什么开发了“React Hooks”(并被社区大肆宣传 😉)的确切原因但不要在生产中使用它们,它们仍处于早期开发阶段(alpha)并且它们的规范/实现可能会改变!

你的问题可以使用令人敬畏的“React Context” API来解决,它允许将数据传递给组件,无论它们在树中嵌套多深。要了解上下文,请阅读上面链接的大量文档。我只会在这里解释一个小而快速的例子:

  1. 创建上下文组件并导出使用者

应用程序.jsx

import React from "react";

// The initial value can be anything, e.g. primitives, object, function,
// components, whatever...
// Note that this is not required, but prevebents errors and can be used as
// fallback value.
const MyContext = React.createContext("anything");

// This component is the so called "consumer" that'll provide the values passed
// to the context component. This is not necessary, but simplifies the usage and
// hides the underlying implementation.
const MyContextConsumer = MyContext.Consumer;

const someData = { title: "Hello World" };

const App = ({ children }) => (
  <MyContext.Provider value={someData}>{children}</MyContext.Provider>
);

export { MyContextConsumer };
export default App;
  1. 在任何组件中导入创建的使用者并使用提供的值

另一个组件.jsx

import React from "react";
import { MyContextConsumer } from "./App";

const AnotherComponent = () => (
  <div>
    <MyContextConsumer>{({ title }) => <h1>{title}</h1>}</MyContextConsumer>
  </div>
);

export default AnotherComponent;
  1. 使用两个上下文组件呈现应用程序
import React from "react";
import ReactDOM from "react-dom";

import App from "./App";
import AnotherComponent from "./AnotherComponent";

const Root = () => (
  <App>
    <AnotherComponent />
  </App>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<Root />, rootElement);

该组件将呈现带有“Hello World”文本的 1 级标题。

编辑 stackoverflow-53648661-how-to-share-state-between-child-component-siblings-in-reactjs

您有不同的方法来解决这种情况。

  • 将状态保持在顶层组件中,并通过 props 传递给子组件
  • 使用状态容器在组件之间保持和共享您的应用程序状态(例如https://redux.js.org/
  • 使用新的React Context功能。Context 提供了一种通过组件树传递数据的方法,而无需在每个级别手动向下传递 props。

请问如何isDropdownOpenedHeadertoNavigation传递状态(例如AnotherComponent

你持有的祖先状态Header和传递状态HaeaderNavigationAnotherComponentprops。请参阅文档中的状态和生命周期以及提升状态

例子:


还有一些其他选项,Arnaud他的回答中有用地提供了这些选项

就像 TJ Said 一样,使用父组件的状态。这样,所有子组件共享一个状态,我假设这就是您想要的。

class ExampleParentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        isDropdownOpened: false
    }
  }

  toggleDropdown() {
    this.setState({
        isDropdownOpened: !isDropdownOpened
    });
  }

  render() {
    return (
        <div>
          <Header open={isDropdownOpened} toggleDropdown={ this.toggleDropdown }/>
          <Navigation open={ isDropdownOpened}/>
          <div>
             <div>
                 <div>
                      <AnotherComponent open={ isDropdownOpened} />
                 </div>
             </div>
          </div>
        </div>
    );
}


class Header extends React.Component {
    render() {
        return (
            <div>
                <button onClick={ this.props.toggleDropdown }>TOGGLE ME</button>
                { isDropdownOpened && (
                    <h1> DROPPED </h1>
                }
            </div>
        );
    }
}