我有两个连接的组件,它们都需要相同的父级,以便它们可以相互通信。但是我希望能够将它们渲染到任何地方,100%分开。我有一个jsfiddle示例来展示这个想法,这是我的问题的一个可怕的解决方案,因为每当我需要更改传入的道具时我都会创建一个新的Img组件。但它显示了这个想法。我觉得我可能会犯这个错误,但也许有一种方法可以将道具传递给Img,而不需要制作新的实例。将非React类作为父级是不可取的。
小提琴说明: 制作一个Img组件,它接受一个道具告诉它是否应该渲染 制作一个Switch组件,用于在单击时更改传递给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'成为某种父类,它为你提供两个在状态/道具领域相互交互的子元素,但是像Example的渲染一样单独渲染。因此,想象一下导入MasterComponent然后像我在Example组件中那样使用它,而不知道幕后发生了什么。这就是我希望的设计模式,但是单独使用React似乎无法实现。
我的MasterComponent版本很糟糕,因为当我真的只想更新它拥有的道具时,我正在使用不同道具的Img新实例替换Img组件。在setState上使用forceUpdate也不好,但我不太关心。
我认为,因为MasterComponent不是具有可以导致重新渲染的状态的反应组件,并且Img和Switch不在渲染函数内部,在那里它们可以有机地接收该状态,也许我的想法不起作用。
答案 0 :(得分:1)
所以...我不知道这是一个好的模式......它不是超级React-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
函数(如果您想手动调用它)。我们使用state
对象进行变异以更改isShowing
状态。
我认为这会起作用。但是,它会存在并完全在React生命周期之外更新状态,我认为这会有问题。所以虽然这可行,但我并不乐观,这是一个好的模式。
我不愿意发布这个不进行测试,并且知道这可能是一个有问题的模式,但我希望它可能会让你走上你正在寻找的道路。
答案 1 :(得分:0)
所以我认为这样做很不错,但要做得更多&#34; React tm&#34;像:
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} />}