React JS中单独组件之间的共享状态如何?
问题描述:
我想创建Dropdown组件。React JS中单独组件之间的共享状态如何?
当我点击DropdownHandler
组件时,我想保存的状态为isOpen
,可以是true
或false
。如果使用true
,则<DropdownContent/>
使用相同的state
来显示内容。而默认情况下,state
isOpen
是false
在<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>
);
}
}
答
我发现基于@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
答
如果你不想使用终极版。 您设置并控制您的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;
答
可以随意更改回调的名称 “的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>
);
}
}
您可以使用[终极版](https://github.com/reactjs/react-redux)这一点。 – Andrew
阅读[提升状态](https://facebook.github.io/react/docs/lifting-state-up.html)和[反思中的思考](https://facebook.github.io/react/docs /thinking-in-react.html) - 他们解释了共享状态的习惯方式。 –