【发布时间】:2017-08-16 01:02:18
【问题描述】:
原始问题
我正在尝试使用 React 呈现项目列表。关键是item共享一个共同的状态,可以被每个item控制。
为了简单起见,假设我们有一个字符串数组。我们有一个List 组件映射到数组上,并生成Item 组件。每个Item 都有一个按钮,当单击该按钮时,它会更改列表中所有项目的状态(我包含了一个代码 sn-p 来传达我正在尝试做的事情)。
我将state 存储在List 组件中,并通过props 将其值传递给每个Item 子级。我遇到的问题是按钮单击(在Item 内)根本没有改变 UI 状态。我认为这个问题与items 在单击按钮时没有改变(这是正确的)这一事实有关,因此 React 不会重新呈现列表(鉴于以下事实,我本来期望某种 UI 更新当List 状态发生变化时,传递给Item 的道具isEditing 会发生变化。
如何让 React 处理这种情况?
注意:点击代码sn-p中的Edit按钮时似乎有脚本错误,但是我在本地运行时没有遇到。相反,不会引发任何错误,但 UI 中的任何内容也不会更新。当我调试它时,我可以看到List 中的状态变化没有传播给它的孩子。
已编辑的问题
鉴于最初的问题不够清楚,我在下面重新表述。
目标
我想呈现React 中的项目列表。每个项目都应显示一个单词和一个Edit 按钮。用户一次只能编辑一项。
验收标准
- 加载后,用户会看到一个单词列表,每个单词旁边都有一个
Edit按钮。 - 当单击项目 1 的
Edit时,只有项目 1 变为可编辑,Edit按钮变为Save按钮。列表中的其余项目不应再显示其对应的Edit按钮。 - 单击项目 0 的
Save后,将显示该项目的新值。所有的“编辑”按钮(对于其余项目)应该会再次可见。
问题
在我最初的实现中,我在父组件 (List) 中存储了一个 edit 状态,但是这个状态没有正确地传播到它的 Item 子组件中。
注意:我最初的实现缺少状态管理逻辑,后来我发现这是罪魁祸首(请参阅下面的回复)。它还有一个 bind 错误,如下面的@Zhang 所述。我把它留在这里以备将来参考,虽然它不是一个很好的例子。
这是我的原始实现:
const items = ['foo', 'bar'];
class List extends React.Component {
constructor(props) {
super(props);
this.state = {
isEditing: false
};
}
toggleIsEditing() {
this.setState((prevState) => {
return {
isEditing: !prevState.isEditing
}
});
}
render() {
return (
<ul>
{items.map((val) => (
<Item value={val}
toggleIsEditing={this.toggleIsEditing}
isEditing={this.state.isEditing}/>
))}
</ul>
);
}
}
class Item extends React.Component {
render() {
return (
<li>
<div>
<span>{this.props.value}</span>
{ !this.props.isEditing &&
(<button onClick={this.props.toggleIsEditing}>
Edit
</button>)
}
{ this.props.isEditing &&
(<div>
<span>...Editing</span>
<button onClick={this.props.toggleIsEditing}>
Stop
</button>
</div>)
}
</div>
</li>
);
}
}
ReactDOM.render(<List />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<body>
<div id="app" />
</body>
【问题讨论】:
-
请更好地描述原始问题。你需要实施什么?看来您尝试这样做的方式是完全错误的。
-
@AlexanderElgin 我已经改写了我的问题以使其更清楚。这是一个很好的练习,因为它帮助我解决了我自己的问题,因为我不得不重新思考我的代码。无论如何,谢谢!
标签: javascript reactjs