简体   繁体   English

React JS - 2 个分离的组件如何能够接收 1 个相同的状态?

[英]React JS - How does 2 separated components able to receive 1 same state?

I am a beginner in using the React JS framework.我是使用 React JS 框架的初学者。 Based on the official React JS documentation, an example is given for changing the state of a component that has a connected hierarchy.基于官方的 React JS 文档,给出了一个更改具有连接层次结构的组件状态的示例。 But in my case this time I split the components for Header and Main separately.但就我而言,这次我将 Header 和 Main 的组件分开。

index.js索引.js

ReactDOM.render(
  <React.StrictMode>
    <Header />
    <Main />
  </React.StrictMode>,
  document.getElementById('root')
);

In the Header component I also have another sub component that functions to activate / deactivate the sidebar which is also a sub menu for the Main component.在 Header 组件中,我还有另一个子组件,用于激活/停用侧边栏,它也是 Main 组件的子菜单。

Header.js头文件.js

import { BtnSidebarOnClick } from './Sidebar';

const Header = () => {
  return (
    <header className="header">
      <div className="header__logo">
        <BtnSidebarOnClick />
        <div className="header__logo_img">
          <a className="link"
            href="/">
            <img src=""
              alt="Schedule App" />
          </a>
        </div>
      </div>
      <nav className="header__nav">
        ...
      </nav>
    </header>
  );
}

export default Header;

Main.js主程序

import { Sidebar } from './Sidebar';

const Main = () => {
  return (
    <main className="main">
      <Sidebar />
      <div className="main__content">
        ...
      </div>
    </main>
  );
}

export default Main;

Notice that the BtnSidebarOnClick and Sidebar components are not connected.请注意, BtnSidebarOnClick 和 Sidebar 组件未连接。 In my case, this time I want to make the Sidebar component accept state to detect whether the button contained in the BtnSidebarOnClick component is clicked / not.就我而言,这次我想让 Sidebar 组件接受状态来检测 BtnSidebarOnClick 组件中包含的按钮是否被单击/未单击。

Sidebar.js侧边栏.js

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

  handleClick() {
    this.setState(state => ({ onClick: !state.onClick }));
  }

  render() {
    return (
      <div className="header__logo_btn">
        <div className="button button--hover button--focus" 
          role="button"
          tabIndex="0"
          onClick={this.handleClick.bind(this)}>
          <i className="material-icons">menu</i>
        </div>
      </div>
    );
  }
}

const Sidebar = () => {
  return (
    <div className="main__sidebar"> {/* set style if BtnSidebarOnClick clicked */}
      <div className="main__sidebar_menu">
        
        <div className="tag-link">
          <a className="link link--hover link--focus link--active"
            href="/">
              <i className="material-icons">insert_drive_file</i>
              <span className="link-title">Files</span>
          </a>
        </div>
      
      </div>
    </div>
  );
}

export { Sidebar, BtnSidebarOnClick };

So how do you set these two components to receive the same state?那么如何设置这两个组件接收相同的状态呢?

TLDR; TLDR; You should pull out the button state into the parent and pass it into the children component.您应该将按钮状态拉出到父组件中并将其传递给子组件。

By the way, it is a common way to have file App.js for your main Application file.顺便说一句,将文件 App.js 用于主应用程序文件是一种常见的方法。 In your case, it should be like this:在你的情况下,它应该是这样的:

index.js索引.js

import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

App.js应用程序.js

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

  handleClick() {
    this.setState(state => ({ isClicked: !state.isClicked }));
  }

  render() {
    return (
      <div>
        <Header onClick={this.handleClick} /> // --> notice
        <Main isClicked={this.state.isClicked} /> // --> notice
      </div>
    )
  }
}

Header.js头文件.js

import BtnSidebar from './BtnSidebar';

const Header = (props) => {
  return (
    <header className="header">
      <div className="header__logo">
        <BtnSidebar onClick={props.onClick} /> // --> notice
        <div className="header__logo_img">
          <a className="link"
            href="/">
            <img src=""
              alt="Schedule App" />
          </a>
        </div>
      </div>
      <nav className="header__nav">
        ...
      </nav>
    </header>
  );
}

Main.js主程序

import Sidebar from './Sidebar';

const Main = (props) => {
  return (
    <main className="main">
      <Sidebar isClicked={props.isClicked} /> // --> notice
      <div className="main__content">
        ...
      </div>
    </main>
  );
}

BtnSidebar.js BtnSidebar.js

const BtnSidebar = (props) => {
  return (
    <div className="header__logo_btn">
      <div className="button button--hover button--focus" 
        role="button"
        tabIndex="0"
        onClick={props.onClick} // --> notice
      >
        <i className="material-icons">menu</i>
      </div>
    </div>
  );
}

Sidebar.js侧边栏.js

const Sidebar = (props) => {
  return (
    <div
      className={
        props.isClicked ? 'main__sidebar-clicked' : 'main__sidebar' // --> notice
      }
    >
      <div className="main__sidebar_menu">
        <div className="tag-link">
          <a className="link link--hover link--focus link--active"
            href="/">
              <i className="material-icons">insert_drive_file</i>
              <span className="link-title">Files</span>
          </a>
        </div>
      
      </div>
    </div>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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