reactjs - 在 React JS 中单击具有特定键的子组件时更改父组件的状态
问题描述
我正在用 React JS 制作一个 Todo 应用程序,我对 React JS 还很陌生。
我制作了两个组件,分别命名为AddComponent
组件TodoItem
。有AddComponent
一个输入和按钮来添加TodoItem
待办事项,每当使用AddComponent
.
当根据其键单击其中的按钮时,我还必须删除子组件TodoItem
,因此它将从父组件的状态中删除该项目AddComponent
。
我面临的问题是我无法在render()
函数之外的任何地方更改状态,因为我在其中TodoItem
使用状态动态生成组件。
更改函数内部的状态render()
会导致无限循环。请帮助如何解决这个问题。
我正在使用使用 CDN 进行样式设置的 Bootstrap 4。
添加组件.js
import React from 'react'
import shortid from 'shortid'
import TodoItem from './TodoItem';
class AddComponent extends React.Component {
constructor() {
super();
this.state = {
todoText: '',
todoList: []
}
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
this.handleTodoClick = this.handleTodoClick.bind(this);
}
handleChange(e) {
e.persist();
this.setState((prevState) => {
return {
todoText: e.target.value,
todoList: prevState.todoList
}
})
}
handleClick() {
this.setState((prevState) => {
return {
todoText: prevState.todoText,
todoList: [{
text: prevState.todoText,
id: shortid.generate()
}, ...prevState.todoList]
}
})
}
handleTodoClick(id) {
const newState = this.state.todoList.filter(todoL => todoL.id === id);
this.setState({ todoList: newState });
}
render() {
const todos = this.state.todoList.map((todo) => {
return (
<TodoItem key={todo.id} value={todo.text} click={this.handleTodoClick(todo.id)}>{todo.text}</TodoItem>
)
})
return (
<div>
<div className="row">
<div className="col-sm-9">
<div className="form-group">
<input
type="text"
className="form-control"
placeholder="Add a Todo"
onChange={this.handleChange}
/>
</div>
</div>
<div className="col-sm-3">
<button
type="button"
className="btn btn-primary btn-block"
onClick={this.handleClick}
>Add
</button>
</div>
</div>
<div>
{todos}
</div>
</div>
)
}
}
export default AddComponent
TodoItem.js
import React from 'react'
class TodoItem extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="alert alert-secondary alert-dismissible fade show">
<button
type="button"
className="close"
onClick={this.props.click}
data-dismiss="alert">×</button>
{this.props.value}
</div>
)
}
}
export default TodoItem
解决方案
试试:https ://codesandbox.io/s/hopeful-moon-duqfe
有两个问题;第一个是过滤器,第二个是设置为单击道具的处理程序回调函数。
第一个问题:过滤器功能应该过滤与您的 id 不匹配的内容,因此您应该使用 NOT equal :
handleTodoClick(id) {
const newState = this.state.todoList.filter(todoL => todoL.id !== id);
this.setState({ todoList: newState });
}
第二个问题:当你将 click prop 设置为处理回调函数时,你应该设置函数本身的引用而不调用它。不是这样的:click={this.handleTodoClick(todo.id)
。这将调用该函数并将 click 属性设置为它的结果,这是未定义的,因为它不会返回任何内容。
所以我已将您的点击道具更改为click={this.handleTodoClick}
const todos = this.state.todoList.map(todo => {
return (
<TodoItem key={todo.id} id={todo.id} value={todo.text} click={this.handleTodoClick}>
{todo.text}
</TodoItem>
);
});
在子组件上, onClick 类似地设置为功能本身onClick={() => this.props.click(this.props.id)}
NOT like onClick={this.props.click(this.props.id)}
。
import React from "react";
class TodoItem extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="alert alert-secondary alert-dismissible fade show">
<button
type="button"
className="close"
onClick={() => this.props.click(this.props.id)}
data-dismiss="alert"
>
×
</button>
{this.props.value}
</div>
);
}
}
推荐阅读
- python - TensorFlow 中的变量到底是什么,我们为什么要使用它们?
- firebase - 在实时数据库或firebase中的firestore之间使用哪个更好?
- c# - 使用 String.StartsWith() 时出现 NullReferenceException
- css - 为什么最后一个层次结构不擦除第一个层次结构?
- javascript - 如何比较两个数组并返回 JavaScript 中的差异
- angular - 如何根据查询参数更改路由或组件
- java - 尝试运行 Chromedriver 时我的配置有什么问题?(智能 / 弹簧)
- python - AWS Elastic Beanstalk Django 配置文件异常
- excel - 如何在Excel中的单元格中创建只能单击而不是选中的超链接
- python - 为什么我的代码没有保存移位字段 df.shift()?