[React]:通过 this.props.children 渲染总是卸载和装载所有子项而不是仅仅重新渲染
[React]: rendering through this.props.children always unmounts and mounts all children instead of just re-rendering
我在 React 中创建了一个具有展开折叠功能的手风琴。
渲染:
<div>
<div>
<label className="label">
{ this.props.label }
</label>
</div>
<div style={{ display: !!this.state.expanded ? "block" : "none" }}>
{ this.props.children } </div>
</div>
我这样称呼它:
<Accordion>
<MyComponent1/>
<MyComponent2/>
<MyComponent3/>
</Accordion>
但每次展开/折叠手风琴时,子组件都会被卸载。正因为如此,他们失去了自己的任何 data/state,我必须把所有东西都放在里面
也不会在发生展开折叠时重新渲染。
发生折叠展开时,子组件不应该只是重新渲染而不是卸载和再次安装。有没有办法达到同样的目的。
我不想保留每个子组件的状态
@Drew Schuster:整个代码-
导出 class 手风琴扩展 React.Component {
constructor(props) {
super(props);
this.state = {
expanded: false
}
}
public render(): JSX.Element {
let className = My_String_Util.format("chevron-", this.state.expanded ? "down" : "right");
return (
<div>
<div onClick={ this._toggle }>
<label className={ className } />
<label className="label"> { this.props.label } </label>
</div>
<If condition={ this.state.expanded }>
<div style={{
display: !!this.state.expanded ? "block" : "none"
}}>{ this.props.children }</div>
</If>
</div>
);
}
private _toggle = (): void => {
this.setState({
expanded: !this.state.expanded
});
}
}
父组件:
render(): JSX.Element {
<Accordion label="Sample Accordion2" expanded={true} >
<MyChildComponent
sampleProp={"aa"}
stringParentProp={"initial string"}/>
<label>"Hello World3"</label>
</Accordion>
}
我的子组件:
constructor(props) {
this.state = {
stateString = this.props.stringParentProp
}
}
render(): JSX.Element {
<div onClick={this._changeLabel}>
<label>this.state.stateString</label>
</div>
}
private _changeLabel() {
this.setState = {
stateString = this.state.stateString + "x";
}
}
每次我们点击子组件到它的标签时,这应该添加 'x'。哪个有效。但是当我们折叠然后再次展开时,标签会重置为 "initial string"
包含的代码有一些错误,导致无法编译。我删除了一些不需要重现此错误的代码,现在在此 codepen 上有了一个可行的解决方案。代码也包含在下面,我使用 React.createClass 而不是扩展 React.Component 但你当然不必这样做。:
const Accordion = React.createClass({
getInitialState: function () {
return { expanded: false }
},
_toggle: function () {
this.setState({
expanded: !this.state.expanded
});
},
render: function () {
return (
<div>
<div onClick={ this._toggle }>
<label className={ className } />
<label className="label"> { this.props.label } </label>
</div>
<div style={{
display: !!this.state.expanded ? "block" : "none"
}}>{ this.props.children }</div>
</div>
);
}
});
const MyChildComponent = React.createClass({
getInitialState: function () {
return { stateString: this.props.stringParentProp}
},
_changeLabel: function () {
this.setState(
{
stateString: this.state.stateString + "x"
})
},
render: function () {
return (
<div onClick={this._changeLabel}>
<label>{this.state.stateString}</label>
</div>
)
}
})
const Parent = () => {
return (
<Accordion label="Sample Accordion2" expanded={true} >
<MyChildComponent
sampleProp="aa"
stringParentProp="initial string"/>
<label>"Hello World3"</label>
</Accordion>
)
}
ReactDOM.render(<Parent/>, document.getElementById('container'))
我在 React 中创建了一个具有展开折叠功能的手风琴。 渲染:
<div>
<div>
<label className="label">
{ this.props.label }
</label>
</div>
<div style={{ display: !!this.state.expanded ? "block" : "none" }}>
{ this.props.children } </div>
</div>
我这样称呼它:
<Accordion>
<MyComponent1/>
<MyComponent2/>
<MyComponent3/>
</Accordion>
但每次展开/折叠手风琴时,子组件都会被卸载。正因为如此,他们失去了自己的任何 data/state,我必须把所有东西都放在里面 也不会在发生展开折叠时重新渲染。
发生折叠展开时,子组件不应该只是重新渲染而不是卸载和再次安装。有没有办法达到同样的目的。 我不想保留每个子组件的状态
@Drew Schuster:整个代码-
导出 class 手风琴扩展 React.Component {
constructor(props) {
super(props);
this.state = {
expanded: false
}
}
public render(): JSX.Element {
let className = My_String_Util.format("chevron-", this.state.expanded ? "down" : "right");
return (
<div>
<div onClick={ this._toggle }>
<label className={ className } />
<label className="label"> { this.props.label } </label>
</div>
<If condition={ this.state.expanded }>
<div style={{
display: !!this.state.expanded ? "block" : "none"
}}>{ this.props.children }</div>
</If>
</div>
);
}
private _toggle = (): void => {
this.setState({
expanded: !this.state.expanded
});
}
}
父组件:
render(): JSX.Element {
<Accordion label="Sample Accordion2" expanded={true} >
<MyChildComponent
sampleProp={"aa"}
stringParentProp={"initial string"}/>
<label>"Hello World3"</label>
</Accordion>
}
我的子组件:
constructor(props) {
this.state = {
stateString = this.props.stringParentProp
}
}
render(): JSX.Element {
<div onClick={this._changeLabel}>
<label>this.state.stateString</label>
</div>
}
private _changeLabel() {
this.setState = {
stateString = this.state.stateString + "x";
}
}
每次我们点击子组件到它的标签时,这应该添加 'x'。哪个有效。但是当我们折叠然后再次展开时,标签会重置为 "initial string"
包含的代码有一些错误,导致无法编译。我删除了一些不需要重现此错误的代码,现在在此 codepen 上有了一个可行的解决方案。代码也包含在下面,我使用 React.createClass 而不是扩展 React.Component 但你当然不必这样做。:
const Accordion = React.createClass({
getInitialState: function () {
return { expanded: false }
},
_toggle: function () {
this.setState({
expanded: !this.state.expanded
});
},
render: function () {
return (
<div>
<div onClick={ this._toggle }>
<label className={ className } />
<label className="label"> { this.props.label } </label>
</div>
<div style={{
display: !!this.state.expanded ? "block" : "none"
}}>{ this.props.children }</div>
</div>
);
}
});
const MyChildComponent = React.createClass({
getInitialState: function () {
return { stateString: this.props.stringParentProp}
},
_changeLabel: function () {
this.setState(
{
stateString: this.state.stateString + "x"
})
},
render: function () {
return (
<div onClick={this._changeLabel}>
<label>{this.state.stateString}</label>
</div>
)
}
})
const Parent = () => {
return (
<Accordion label="Sample Accordion2" expanded={true} >
<MyChildComponent
sampleProp="aa"
stringParentProp="initial string"/>
<label>"Hello World3"</label>
</Accordion>
)
}
ReactDOM.render(<Parent/>, document.getElementById('container'))