#javascript #reactjs
#javascript #reactjs
Вопрос:
У меня проблема с отправкой состояния от дочернего элемента к родительскому. После нажатия на меню в главном компоненте я хочу изменить состояние active и отправить это active в компонент боковой панели, потому что я хочу скрыть / показать боковую панель, зависящую от активного класса из 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>
);
}
Комментарии:
1. Где вы используете
<Sidebar />
компонент?2. В основном файле App.js .
3. Не могли бы вы также поделиться этим файлом? Спасибо!
4. Хорошо, я добавляю App.js на вопрос
5. Всякий раз, когда вы хотите передать состояние из дочернего компонента в родительский компонент, вы должны поднять состояние до родительского компонента. Вам нужно будет поддерживать состояние в самом родительском компоненте, а также добавлять обработчики событий для изменения состояния прямо в родительском компоненте. И затем вы можете передать это состояние в качестве реквизита дочернему компоненту. Таким образом, он сохраняет состояние, и ваш родительский компонент также имеет доступ к состоянию.
Ответ №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
Комментарии:
1. Спасибо, чувак, я не знал, что я могу установить setActivate в качестве prop 🙂 Но сейчас работает очень хорошо 🙂
Ответ №2:
С контекстным api и хуками больше не требуется сверление реквизитов. Вы можете просто обернуть родительский и дочерний компоненты в поставщике контекста и использовать перехватчик useContext от react для управления состоянием между 2 компонентами. у Кента си Доддса есть хорошая статья с примерами здесь
Комментарии:
1. Интересно почитать, Context API действительно предлагает альтернативу prop drilling, однако для этого требуется больше шаблонов. Итак, как вы выбираете между детализацией реквизита и контекстом на практике? Используете ли вы жесткие правила, такие как: не сверлить более чем на 2 уровнях или более чем на 3 компонентах?
2. на самом деле это просто зависит от сложности состояния приложения. в более крупных проектах я считаю предпочтительным использовать несколько контекстов для группировки компонентов, которые зависят от состояния, которое содержит каждый контекст (почти как ограниченный контекст в domain driven design). Что касается жестких правил, то это действительно зависит от инженера, который работает над проектом, я обычно придерживаюсь чего-либо на 3 уровня ниже или состояния, которое используется более чем 3 компонентами, я склонен использовать контекст.
3. Спасибо, полезно получить такую практическую информацию о дизайне React! У вас был бы хороший материал по дизайну, управляемому доменом, с React?
4. На самом деле это не относится к React, но я настоятельно рекомендую книгу Вона Вернона Domain Driven Design Distilled, если вы заинтересованы в DDD.