如何基于另一个组件的事件处理程序更新一个组件?

时间:2018-10-27 14:00:16

标签: javascript html reactjs dom jsx

我的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,并且由于我试图从另一个组件访问组件,所以我不确定是否应该这样做。 预先感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

为了连接组件,您应该使用商店在所有组件之间共享应用程序状态。像 Redux 之类的东西就可以做到。

主要思想是您更改Header组件中的状态,并且补充工具栏将侦听此状态,并在需要时进行自我更新。

答案 1 :(得分:1)

方法很少。

  1. 您可以使用Redux。
  2. 使用React Context API https://reactjs.org/docs/context.html

您可以执行以下操作

// 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();