【问题标题】:How to send state from Child component to another component in React如何将状态从子组件发送到 React 中的另一个组件
【发布时间】:2020-12-18 03:25:35
【问题描述】:

我在将状态从子级发送到父级时遇到问题。 单击主组件中的菜单后,我想更改状态活动并将此活动发送到边栏组件,因为我想隐藏/显示边栏取决于 css 中的活动类。在 Vanilla JS 中这很容易,但在 React 中我有点困惑。

主要:

import Menu from "./Menu";

import "./Styles.css";

import teamsdb from "./teamsdb";

const Main = ({ name }) => {
  
  return (
    <div>
      <Menu />
      <h1>Main</h1>
      <h4>{teamName}</h4>
    </div>
  );
};

菜单:

const Menu = () => {
  const [active, setActive] = useState(false);
  const changeMenu = () => {
    setActive(!active);
  };
  return <button onClick={changeMenu}>Menu</button>;
};

export default Menu;

侧边栏:

const Sidebar = () => {
  const [searchTerm, setSearchTerm] = React.useState("");
  const handleChange = e => {
    setSearchTerm(e.target.value);
    console.log("Search: ", e.target.value);
  };

  return (
    <div className={active ? 'sidebar active' : 'sidebar'}>
      <div className="sidebar__header">
        Header
        <button>Colors</button>
      </div>
      <div className="sidebar__search">
        <input
          type="text"
          placeholder="Search"
          value={searchTerm}
          onChange={handleChange}
        />
      </div>
      <Teams search={searchTerm} />
    </div>
  );
};

App.js

import React from "react";
import "./App.css";
import Sidebar from "./components/Sidebar";
import Main from "./components/Main";

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";    
function App() {
      return (
        <div className="App">
          <div className="app__body">
            <Router>
              <Sidebar />
              <Switch>
                <Route path="/team/:teamId">
                  <Main />
                </Route>
                <Route exact path="/">
                  <Main />
                </Route>
              </Switch>
            </Router>
          </div>
        </div>
      );
    }

【问题讨论】:

  • 你在哪里使用&lt;Sidebar /&gt;组件?
  • 在主文件 App.js.
  • 你能把那个文件也分享一下吗?谢谢!
  • 好的,我将 App.js 添加到问题中
  • 当你希望将状态从子组件传递到父组件时,你应该将状态提升到父组件。您必须维护父组件本身的状态,并添加事件处理程序以更改父组件中的状态。然后您可以将此状态作为道具传递给子组件。这样,它就可以保持状态,并且您的父组件也可以访问该状态。

标签: javascript reactjs


【解决方案1】:

您应该将您的状态提升到第一个共同祖先组件,在您的情况下:App。这样,您可以通过将状态和突变函数 (setActive) 作为 prop 传递来在其所有后代中使用它:

      App    // Put active state here, pass down active and setActive as prop
       ^
       |
  +----+-----+
  |          |
  +          +
Sidebar     Main  // Pass down active and setActive as prop
             ^
             |
             |
            Menu  // Use setActive to modify state in App

这在 React 文档中有解释:https://reactjs.org/docs/lifting-state-up.html

【讨论】:

  • 谢谢你,我不知道我可以将 setActivate 设置为道具 :) 但现在工作得很好:)
【解决方案2】:

使用 context api 和 hooks 不再需要钻孔。您可以简单地将父项和子项包装在上下文提供程序中,并利用 react 的 useContext 挂钩来管理 2 个组件之间的状态。 kent c dodds 有一篇很好的文章,里面有例子here

【讨论】:

  • 有趣的是,Context API 确实提供了道具钻孔的替代方案,但它需要更多样板。那么在实践中如何在道具钻孔和上下文之间进行选择呢?您是否使用硬性规则,例如:钻取不超过 2 个级别,或不超过 3 个组件?
  • 这真的取决于应用程序状态的复杂性。在更大的项目中,我发现最好利用多个上下文来对依赖于每个上下文所保持状态的组件进行分组(几乎就像领域驱动设计中的有界上下文)。就硬性规则而言,这完全取决于从事该项目的工程师,我通常坚持任何 > 3 个级别或被超过 3 个组件摄取的状态,我倾向于使用上下文。
  • 谢谢,获得这种关于 React 设计的实用信息很有价值!你有关于 React 领域驱动设计的好资料吗?
  • 它并不是真正特定于 React,但如果你对 DDD 感兴趣,我强烈推荐 Vaughn Vernon 的 Domain Driven Design Distilled 一书。
猜你喜欢
  • 2021-09-29
  • 1970-01-01
  • 2020-06-05
  • 2020-07-25
  • 2018-11-03
  • 2021-01-11
  • 2019-02-26
  • 1970-01-01
  • 2016-04-20
相关资源
最近更新 更多