我有一个设置,其中有一个需要在视图中显示的React组件图。
也有许多输入选择处理程序会更新父组件的状态,但是在状态更新后,将调用“父组件”渲染方法,但子组件不会刷新“值”。
我在这里想念什么?我有点困惑
问题Stackblitz的最小复制。
import React, { PureComponent } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
export const ReactExample = ({ name, value, handleChange }) => (
<select name={name} value={value} onChange={handleChange}>
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
)
const Section = props => {
return (
<div>
{props.header}
<br />
{props.primaryNode}
<br />
{props.bottom}
</div>
);
};
class App extends React.PureComponent {
state = {
current: 'B'
};
constructor(props) {
super(props);
}
show = [5, 6, 3, 5, 7, 8, 77, 8, 90];
primaryNode = () => {
const filterData = this.show;
return (<div>{filterData}----{this.state.current} // doesn't get updated even though state updates after dropdown</div>);
};
bottom = () => {
return (
<ReactExample name="fruit" value={this.state.current} handleChange={this.handleChange} />
)
}
handleChange = (event) => {
console.log(event.target.value); // always logged and state updated with no change in value
this.setState({ current: event.target.value });
}
data = ["A", "B", "C"];
map = {
"A": (<Section primaryNode={this.primaryNode()} bottom={this.bottom()} header={"A"} />),
"B": (<Section primaryNode={this.primaryNode()} header={"B"} />),
"C": (<Section primaryNode={this.primaryNode()} header={"C"} />)
};
render() {
return (<div>{this.data.map(d => this.map[d])}</div>)
}
}
render(<App />, document.getElementById('root'));
答案 0 :(得分:1)
我认为通过将所有这些值作为类属性来保存,这比需要使它更加混乱。它们不更新的原因是因为this.map
仅定义了一次。您根本不需要地图,只需在render
函数内部直接渲染节点即可,该函数在状态更改时被调用:
render() {
return (
<div>
<Section primaryNode={this.primaryNode()} bottom={this.bottom()} header={"A"} />
<Section primaryNode={this.primaryNode()} header={"B"} />
<Section primaryNode={this.primaryNode()} header={"C"} />
</div>
)
}
如果您真的希望它成为地图,请在render
内定义它:
render() {
const map = {
"A": <Section primaryNode={this.primaryNode()} bottom={this.bottom()} header={"A"} />,
"B": <Section primaryNode={this.primaryNode()} header={"B"} />,
"C": <Section primaryNode={this.primaryNode()} header={"C"} />
};
return <div>{this.data.map(d => map[d])}</div>
}
答案 1 :(得分:1)
在第一次渲染组件时,仅一次初始化类字段map
。更改状态并不重要,该变量保存的数据完全相同,并且不会随时间变化。
解决方案之一是将该变量移至render中:
render() {
const map = {
"A": (<Section primaryNode={this.primaryNode()} bottom={this.bottom()} header={"A"} />),
"B": (<Section primaryNode={this.primaryNode()} header={"B"} />),
"C": (<Section primaryNode={this.primaryNode()} header={"C"} />)
};
return (<div>{this.data.map(d => this.map[d])}</div>)
}
或者您可以将map
字段转换为方法:
map = () => ({
"A": (<Section primaryNode={this.primaryNode()} bottom={this.bottom()} header={"A"} />),
"B": (<Section primaryNode={this.primaryNode()} header={"B"} />),
"C": (<Section primaryNode={this.primaryNode()} header={"C"} />)
});
render() {
return (<div>{this.data.map(d => this.map()[d])}</div>)
}
因此map
返回的数据始终是最新的。
答案 2 :(得分:1)
不确定您要做什么,但是听起来您想通过状态更改来更新A / B / C值。问题在于您是在地图对象之前 render()
中定义primaryNode,而不是在render()
的 inside 中定义(总是重新渲染)当状态更改时,请尝试以下操作:
import React, { PureComponent } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
const Section = item => (
<>
<br/>
<section>
{item.header}
<br />
{item.primaryNode}
<br />
{item.bottom}
</section>
</>
);
class App extends React.PureComponent {
constructor(props) {
super(props);
}
state = {
current: 'B'
}
data = ["A", "B", "C"];
show = [5, 6, 3, 5, 7, 8, 77, 8, 90];
bottom = () => (
<select name={"fruit"} value={this.state.current} onChange={this.handleChange}>
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
);
handleChange = (event) => (
this.setState({ current: event.target.value })
);
primaryNode = () => (
<div className="primary-node">
{this.show} ---- {this.state.current}
</div>
);
render() {
return (
<>
State Value - {this.state.current}
<br/>
<br/>
<br/>
{this.data.map(el => (
<Section
bottom={el === "A" && this.bottom()}
header={el}
primaryNode={this.primaryNode()}
/>
))}
</>
);
}
}
render(<App />, document.getElementById('root'));
答案 3 :(得分:0)
尝试在map
方法内移动render()
。
状态更改时会触发render()
,因此它是您要寻找的地方