Javascript 试图在react中创建特殊的设计模式,但不确定如何实现

Javascript 试图在react中创建特殊的设计模式,但不确定如何实现,javascript,reactjs,design-patterns,components,Javascript,Reactjs,Design Patterns,Components,我有两个连接的组件,它们都需要相同的父级,这样它们就可以相互通信。然而,我希望能够使他们在任何地方,100%分开。我举了一个例子来说明这个想法,这是一个糟糕的解决方案,因为每当我需要更改传入的道具时,我都会创建一个新的Img组件。但它表明了这个想法。我觉得我可能做错了,但也许有一种方法可以在不创建新实例的情况下将道具传递给Img。让一个非React类作为父类肯定不是很理想 胡乱解释: 制作一个接收道具的Img组件,告诉它是否应该渲染 制作一个开关组件,在单击时将更改传递到Img组件的道具 它们可

我有两个连接的组件,它们都需要相同的父级,这样它们就可以相互通信。然而,我希望能够使他们在任何地方,100%分开。我举了一个例子来说明这个想法,这是一个糟糕的解决方案,因为每当我需要更改传入的道具时,我都会创建一个新的Img组件。但它表明了这个想法。我觉得我可能做错了,但也许有一种方法可以在不创建新实例的情况下将道具传递给Img。让一个非React类作为父类肯定不是很理想

胡乱解释: 制作一个接收道具的Img组件,告诉它是否应该渲染 制作一个开关组件,在单击时将更改传递到Img组件的道具

它们可以单独呈现在任何位置,并由父类控制。 forceUpdate只是为了让这个示例工作,我知道这不是一个很好的用途

守则:

const Img = (props) => {

  return (
    <div><img style={{ display: props.isShowing ? 'inline' : 'none', width: '100px' }} src="http://blog.nationalgeographic.org/wp-content/uploads/2010/04/Greatest-Nature-Photographs-of-All-Time-3.jpg" /></div>
  );
};

const Switch = (props) => {

  return (
    <div style={{ width: '50px', height: '50px', background: 'black', color: 'white'}} onClick={() => props.toggleImg()}>
    click me
    </div>
  );
};

class MasterComponent {
  constructor(outerThis) {
    this.outerThis = outerThis;
    this.toggleState = true;
    this.img = <Img isShowing={ true } />;
    this.switch = <Switch toggleImg={ () => this.toggleImg() } />;
  }

  toggleImg() {
    this.toggleState = !this.toggleState;
    this.img = <Img isShowing={ this.toggleState } />;
    this.outerThis.forceUpdate();
  }

}


class Example extends React.Component {
    constructor(props) {
        super(props);
    this.masterComponent = new MasterComponent(this);
  }

  render() {
    return <div>
    {this.masterComponent.img}
    {this.masterComponent.switch}
    </div>;
  }
}
编辑: 所以问题基本上是这样的。我希望“MasterComponent”是某种父级,它为您提供两个子级,它们在状态/道具领域中相互交互,但像示例中的渲染一样单独渲染。因此,想象一下导入MasterComponent,然后像我在示例组件中所做的那样使用它,而不知道幕后发生了什么。这是我所希望的设计模式,但单凭React似乎无法实现

我的MasterComponent版本不好,因为我正在用一个新的Img实例替换Img组件,而我只是想更新它拥有的道具。在setState上使用forceUpdate也很糟糕,但我不太担心这一点


我认为,由于MasterComponent不是一个带有状态的react组件,它的状态可能会导致重新渲染,并且Img和Switch不在渲染函数中,它们可以有机地接收该状态,因此我的想法可能不起作用。

所以我认为这是非常好的,但是,让它更像react tm:

const Img = (props) => {

  return (
    <div>
      <img
        style={{ display: props.isShowing ? 'inline' : 'none', width: '100px' }}
        src="http://blog.nationalgeographic.org/wp-content/uploads/2010/04/Greatest-Nature-Photographs-of-All-Time-3.jpg"/>
    </div>
  );
};

const Switch = (props) => {

  return (
    <div
      style={{ width: '50px', height: '50px', background: 'black', color: 'white'}}
      onClick={props.toggleImg}>
    click me
    </div>
  );
};

class MasterComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      showImg: true,
    };

    this.toggleImg = this.toggleImg.bind(this);
  }

  toggleImg() {
    this.setState({showImg: !this.state.showImg});
  }

  render() {
    return <div>
      <Img isShowing={this.state.showImg} />
      <Switch toggleImg={this.toggleImg} />
    </div>;
  }
}


class Example extends React.Component {
  render() {
    return <div>
      <MasterComponent />
    </div>;
  }
}


ReactDOM.render(
  <Example />,
  document.getElementById('container')
);
这样更具可组合性,并且使用react Components类

此外,您可能对以下内容感兴趣:

{this.state.showImg && <Img isShowing={true} />}

所以。。。我不知道这是一个好的模式。。。这不是超级反应y,但我认为它会实现你想要的。我还没有测试过,但我想是这样的:

function getImgSwitchPair() {

  const state = {
    isShowing: true
  };

  const toggleImg = () => {
    state.isShowing = !state.isShowing;
  };

  const Img = () => {
    return (
      <div><img style={{ display: state.isShowing ? 'inline' : 'none', width: '100px' }} src="http://blog.nationalgeographic.org/wp-content/uploads/2010/04/Greatest-Nature-Photographs-of-All-Time-3.jpg" /></div>
    );
  };

  const Switch = () => {
    return (
      <div style={{ width: '50px', height: '50px', background: 'black', color: 'white'}} onClick={toggleImg}>
      click me
      </div>
    );
  };

  return {
    Img,
    Switch,
    toggleImg
  };

}


class Example extends React.Component {
  constructor(props) {
        super(props);
        const {Img, Switch} = getImgSwitchPair();
        this.Img = Img;
        this.Switch = Switch;
  }

  render() {
    return ( 
      <div>
        <Img/>
        <Switch/>
      </div>
    );
  }
}
getImgSwitchPair生成并返回一个耦合的Img和Switch组件,以及toggleImg函数(如果要手动调用)。我们使用一个状态对象来改变显示状态

我想这会管用的。然而,它将在React生命周期之外完全存在并更新状态,我认为这是有问题的。因此,虽然这可能有效,但我不确定这是一个好模式


我很犹豫是否发布此w/o测试,因为我知道这可能是一个有问题的模式,但我希望它能让您找到您想要的东西……

建议使用setState方法来改变状态。因此,您遇到的问题是,提升状态有时会成为一个繁重或有问题的模式,尤其是在这种情况下。相反,您可以利用这样的功能,它允许您将API直接注入组件,而不管它位于层次结构中的什么位置。或者,如果Redux看起来有些过分,你也可以创建自己的服务架构来支持它。@AlexanderNied hey man人们不需要Redux来开发这样的简单应用程序,因为在我看来,这不是一个好的推荐。还有@OP这个问题不是很清楚。@AlexanderNied我在制作的应用程序中使用Redux,但我希望这是一件独立的事情。这就是我用MasterComponent隔离所有东西的原因。我的用例比这更复杂,因此用新的道具替换旧的组件是不现实的。@Omar我将尝试改写这个问题这更像是反应,当然,但目标是将Img和开关分开,而不是包装在主组件中,这就是为什么我没有把主成分变成真正的反应成分。在示例组件中,我希望能够将Img和交换机放在不同的区域。在我的示例中,我刚刚创建了MasterComponent的一个新实例,然后我能够将Img和Switch分开。我一直在寻找一种更具反应性的方法。很抱歉,我不知道这有什么不同,它们可以单独使用,您不需要主组件,可以直接在示例中使用它们,我想我只是不明白您想要实现什么,或者更重要的是为什么?,无论如何,希望我的例子对你有所帮助。对不起,我知道我解释得不好,谢谢你的例子。我想这是因为有两个相互依赖的组件,所以我希望它们在一个导入下生活在一起,即使它们的渲染是分开的,并且它们不必彼此相邻。它们可以直接用于示例b