2017-02-21 60 views
1

我想创建Dropdown组件。React JS中单独组件之间的共享状态如何?

当我点击DropdownHandler组件时,我想保存的状态为isOpen,可以是truefalse。如果使用true,则<DropdownContent/>使用相同的state来显示内容。而默认情况下,stateisOpenfalse<Dropdown />组件

我怎么能做到这一点吗?

App.jsx

import React from 'react'; 
import {Dropdown, DropdownHandler, DropdownContent} from '../../components/Dropdown/Dropdown.jsx'; 

class HeaderConnected extends React.Component { 

    constructor(props) { 
     super(props); 
    } 

    render() { 
     return (
      <div> 
       <Dropdown> 
       <DropdownHandler> 
        <Avatar title="Roberto"></Avatar> 
       </DropdownHandler> 
       <DropdownContent> 
        <li>Menu</li> 
        <li>Settings</li> 
       </DropdownContent> 
       </Dropdown> 
      </div> 
     ); 
    } 

} 

export default HeaderConnected; 

Dropdown.jsx

export class Dropdown extends React.Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      opened: false 
     } 
    } 

    render() { 

     return (
      <div className="DROPDOWN"> 
       {this.props.children} 
      </div> 
     ); 
    } 

} 

export class DropdownHandler extends React.Component { 

    constructor(props) { 
     super(props); 
    } 

    render() { 

     return (
      <div className="DROPDOWN__HANDLER"> 
       {this.props.children} 
      </div> 
     ); 
    } 

} 

export class DropdownContent extends React.Component { 

    constructor(props) { 
     super(props); 
    } 

    render() { 

     return (
      <div className="DROPDOWN__CONTENT"> 
       {this.props.children} 
      </div> 
     ); 
    } 

} 
+0

您可以使用[终极版](https://github.com/reactjs/react-redux)这一点。 – Andrew

+0

阅读[提升状态](https://facebook.github.io/react/docs/lifting-state-up.html)和[反思中的思考](https://facebook.github.io/react/docs /thinking-in-react.html) - 他们解释了共享状态的习惯方式。 –

回答

1

我发现基于@Andrew答案的解决方案。不知道这是否正确。但它解决了共享状态,只能通过Dropdown使用。我通过处理程序和内容通过道具

你觉得呢?

App.jsx

import React from 'react'; 
import {Dropdown} from '../../components/Dropdown/Dropdown.jsx'; 

class HeaderConnected extends React.Component { 

    constructor(props) { 
     super(props); 
    } 

    render() { 
     return (
      <div> 
       <Dropdown handler={<Avatar title="Roberto" />}> 
        <li>Menu</li> 
        <li>Settings</li> 
       </Dropdown> 
      </div> 
     ); 
    } 

} 

export default HeaderConnected; 

Dropdown.jsx

export class Dropdown extends React.Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      opened: false 
     } 
    } 

    render() { 

     return (
      <div className="DROPDOWN"> 
       <div className="DROPDOWN_HANDLER" onClick="..."> 
        {this.props.handler} 
       </div> 
       <div className="DROPDOWN_CONTENT"> 
        {this.props.children} 
       </div> 
      </div> 
     ); 
    } 

} 
+1

总是在组件中声明道具,你可以移除你的构造函数并声明你的直接在组件中查看(查看我的答案)。 – Kornflexx

1

如果你不想使用终极版。 您设置并控制您的opend状态的子组件,并将其设置为DropdownContent与道具。所以当你通过点击DropdownHandler来改变opend时,你的DropdownContent会收回新的propse并调用重新渲染。

import React from 'react'; 
import {Dropdown, DropdownHandler, DropdownContent} from '../../components/Dropdown/Dropdown.jsx'; 

class HeaderConnected extends React.Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      opened: false 
     } 
    } 
    onClick(){ 
     let condition = this.state.opened; 
     this.setState({opened: !condition }); 
    } 
    render() { 
     return (
      <div> 
       <Dropdown> 
       <DropdownHandler onClick={this.onClick.bind(this)}> 
        <Avatar title="Roberto"></Avatar> 
       </DropdownHandler> 
       <DropdownContent opened={this.state.opened}> 
        <li>Menu</li> 
        <li>Settings</li> 
       </DropdownContent> 
       </Dropdown> 
      </div> 
     ); 
    } 

} 

export default HeaderConnected; 
+0

是啊!非常快的答案!谢谢。这可以是工作,我明白了。但是 如果这些状态不在,那么用什么组件'Dropdown,DropdownHandler,DropdownContent'?因为我想在任何地方使用这个'Dropdown'组件。不仅在'HeaderConnected' – Steffi

+0

我认为,你应该做一个可重用的组件下拉,就像你的组件HeaderConnected现在一样。并发送带有道具的内容。 – Andrew

+0

是的,我想做类似的事情,但如何发送带有道具的内容并在下拉组件中保持状态? – Steffi

0

可以随意更改回调的名称 “的OnOpen”

export class Dropdown extends React.Component { 

    state = { 
     open: false 
    } 

    handleOpen =() => { 
     this.setState({open: !this.state.open}); 
    } 

    render() { 

     return (
      <div className="DROPDOWN"> 
       {React.cloneElement(this.props.children, { open: this.state.open, onOpen: this.handleOpen })} 
      </div> 
     ); 
    } 

} 

export class DropdownHandler extends React.Component { 

    static propTypes = { 
     open: React.PropTypes.bool.isRequired, 
     onOpen: React.PropTypes.func.isRequired 
    } 

    render() { 

     return (
      <div className="DROPDOWN__HANDLER" onClick={this.props.onOpen}> 
       {this.props.children} 
      </div> 
     ); 
    } 

} 

export class DropdownContent extends React.Component { 

    static propTypes = { 
     open: React.PropTypes.bool.isRequired, 
     onOpen: React.PropTypes.func.isRequired 
    } 

    render() { 
     // handle visibility here 
     return (
      <div className="DROPDOWN__CONTENT"> 
       {this.props.children} 
      </div> 
     ); 
    } 

} 
+0

我不明白这个解决方案:( – Steffi

+0

下拉组件将包含dropdownhandler和dropdowncontent,它通过道具给他们打开状态,他们可以调用onOpen的道具来改变open的值,我假设你的处理程序组件会调用这个回调函数(onOpen)。 – Kornflexx

+0

我现在明白了。您对我发布的解决方案有何看法?我不确定。 – Steffi

相关问题