我的index.js文件中有两个组件(页眉和边栏),如下所示
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import {
BrowserRouter as Router,
Route
} from "react-router-dom";
import './index.scss';
import './responsive.scss';
import Sidebar from './sidebar';
import Header from './header';
import Home from './home';
import Products from './products';
import Variant from './variant';
import Variety from './variety';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<Router>
<div className="wrapper">
<Header />
<Sidebar />
<div id="content">
<Route exact path="/" component={Home} />
<Route path="/products" component={Products} />
<Route path="/variant" component={Variant} />
<Route path="/variety" component={Variety} />
</div>
</div>
</Router>
, document.getElementById('root'));
serviceWorker.unregister();
我的Header组件中有一个按钮,我想向其中添加一个onClick事件处理程序,因此,当单击Sidebar组件中的侧栏时,将被切换。 现在我的问题是我无法连接这两个组件。我什至尝试使用此链接How To Pass Events Between Components中的建议,但问题是该事件的目标是更改子组件中定义的所有元素。 我已经阅读了一些有关createPortal()的信息,但是建议访问组件外部的DOM,并且由于我试图从另一个组件访问组件,所以我不确定是否应该这样做。 预先感谢您的帮助。
答案 0 :(得分:1)
为了连接组件,您应该使用商店在所有组件之间共享应用程序状态。像 Redux 之类的东西就可以做到。
主要思想是您更改Header组件中的状态,并且补充工具栏将侦听此状态,并在需要时进行自我更新。
答案 1 :(得分:1)
方法很少。
您可以执行以下操作
// IN MAIN FILE
state ={
sidebarOpen : false
}
<header toggleSidebar = { this.toggleSidebar} />
<sidebar sidebarOpen = { this.state.sidebarOpen} />
toggleSidebar(){
//UPDATE STATE
this.setState({
sidebarOpen : !(this.state.sidebarOpen)
})
}
// IN HEADER
onButtonClick(){
this.props.toggleSidebar()
}
IN SIDEBAR
componentWillReceiveProps(props){
//LOGIC FOR UPDATING SIDEBAR YOU WILL RECIEVE UPDATED STATE HERE
}
答案 2 :(得分:1)
首先,简单地连接这两个组件。React中的数据传输建议从父组件传递到子组件。这是提升状态。因此,通常,使用回调更改标头的父组件并传递数据返回到侧边栏。现在,redux可以很好地与react配合使用。因此,只需为侧边栏设置一个状态,并在Header的onClick中绑定一个函数,然后在onClick中添加一些内容即可,例如:
<header onClick = { this.expand.bind(this)} />
<sidebar sidebar = { this.state.sidebar} />
顺便说一句,react为我们提供了一些传递数据的方法。例如,当组件嵌套复杂且难以找到通用父组件时,使用上下文。
第二,“该事件针对子组件中定义的所有元素的更改”。此问题是由于反应的工作原理。您可以使用shouldComponentUpdate来避免这种情况。但此处不推荐。
第三,关于React Portal,它已添加到React v16中。它用于将子组件呈现在父组件之外。如果您想知道这个答案,这个答案很好。How to use ReactDOM.createPortal() in React 16?。侧边栏和标头组件处于同一级别。因此,我认为这不是必需的。
答案 3 :(得分:1)
每个人都回答,这是一些很好的解决方案。但是您也提到了自己的限制。您也可以尝试以下一种。
let showSidebar = true;
// Function to handle toggle
const handleClick = () => {
showSidebar = !showSidebar
renderApp()
}
// Make renderApp function
const renderApp = () => {
ReactDOM.render(
<Router>
<div className="wrapper">
<Header handleClick={handleClick}/> // call this function onClick inside your Header component
{ showSidebar && <Sidebar /> } // toggle the Sidebar
<div id="content">
<Route exact path="/" component={Home} />
<Route path="/products" component={Products} />
<Route path="/variant" component={Variant} />
<Route path="/variety" component={Variety} />
</div>
</div>
</Router>
, document.getElementById('root'));
};
renderApp(); // Call renderApp for the first time
serviceWorker.unregister();