我正在使用ReactJS创建决策矩阵应用。我无法弄清楚ReactJS如何更新同一类型的直接子节点的同一类型的多个组件。
问题:只有一个组件更新,而相同的兄弟姐妹不会
重现的步骤:
1)在第一个输入框中输入字符
2)在第二个输入框中输入字符
3)按“添加任务”按钮
4)任务现在在所有5个类别div中。输入5次是同一个任务。
5)在相同任务的输入框之一中输入类别编号(1-4)
6)仅对您输入输入的任务进行更新,但不对任何其他相同任务进行更新
即时预期效果:每个相同的任务将以相同的方式更新其类别编号
更好的预期效果:更新任务的类别编号,使其仅显示在匹配类别编号的框中(或者,如果没有类别编号,则显示在“无标签”类别框中)
Snippets / Functions / etc查看:handleListTaskChange,handleTaskChange,handleCategoryChange
JSFiddle Link:https://jsfiddle.net/t9etyjr1/
类别包含任务
// -Categories (4)
// (urgent/important, urgent/unimportant, non-urgent/important, non-urgent/unimportant)
const Category = React.createClass({
handleTaskDelete(taskId){
this.props.onListTaskDelete(taskId)
},
handleTaskChange(taskId, categoryId){
this.props.onListTaskChange(taskId, categoryId)
},
render(){
let opts = {}
function predicate(condition, test){
if (condition){
return () => test
}
return () => true
}
const taskNodes = this.props.data
// .filter((task, index) => {
// return predicate(
// !this.props.isLast,
// parseInt(task.category, 10) === index + 1)()
// })
.map((task, index) => {
return (
<Task
author={task.task.author}
text={task.task.text}
key={task.task.id}
taskKey={task.task.id}
onTaskChange={this.handleTaskChange}
onTaskDelete={this.handleTaskDelete}
category={task.category}
/>
)
})
return (
<div className="category">
<h2>{this.props.categoryTitle}</h2>
{taskNodes}
</div>
)
}
})
Matrix Box拥有一切
// -MatrixBox
const MatrixBox = React.createClass({
getInitialState(){
return {
taskData: [],
categoryData: [
{name: 'urgent/important (1)'},
{name: 'non-urgent/important (2)'},
{name: 'urgent/unimportant (3)'},
{name: 'non-urgent/unimportant (4)'},
{name: 'no label'}
]}
},
handleListTaskDelete(taskId){
const tasks = this.state.taskData
const newTasks = tasks.filter(task => (task.task.id !== taskId))
this.setState({taskData: newTasks})
},
handleListTaskChange(taskId, categoryId){
const tasks = this.state.taskData
const newTasks = tasks.map(task => {
if (task.task.id !== taskId) return task
task.task.category = categoryId
return task
})
this.setState({taskData: newTasks})
},
handleTaskSubmit(task){
const tasks = this.state.taskData
task.id = Date.now()
const newTasks = tasks.concat([{task, category: ''}])
this.setState({taskData: newTasks})
},
render(){
console.log(this.state.taskData)
const categoryNodes = this.state.categoryData.map((category, index, arr)=>{
return (
<Category
categoryTitle={category.name}
key={index}
categoryKey={index}
onListTaskDelete={this.handleListTaskDelete}
onListTaskChange={this.handleListTaskChange}
isLast={(index + 1 >= arr.length)}
data={this.state.taskData}
/>
)
})
return (
<div className="matrixBox">
{categoryNodes}
<TaskForm onTaskSubmit={this.handleTaskSubmit} />
</div>
)
}
})
任务进入类别框
// -Tasks
const Task = React.createClass({
getInitialState(){
return {category: ''}
},
handleDeletePress(e){
e.preventDefault()
this.props.onTaskDelete(this.props.taskKey)
},
handleCategoryChange(e){
this.setState({category: e.target.value})
this.props.onTaskChange(this.props.taskKey, e.target.value)
},
render(){
let category = this.state.category
if(category !== ''
&& parseInt(category, 10) < 5
&& parseInt(category, 10) > 0
) {
console.log('New value is ' + this.state.category)
}
return (
<div className="task">
{this.props.author}
{this.props.text}
<form onSubmit={this.handleDeletePress}>
<button>Delete</button>
<input
type="text"
placeholder="Category #"
value={this.state.category}
onChange={this.handleCategoryChange}
maxLength="1"
/>
</form>
</div>
)
}
})
使用任务表单创建任务
// -TaskForm
const TaskForm = React.createClass({
getInitialState(){
return {author: '', text: ''}
},
handleAuthorChange(e){
this.setState({author: e.target.value})
},
handleTextChange(e){
this.setState({text: e.target.value})
},
handleSubmit(e){
e.preventDefault()
let
author = this.state.author.trim(),
text = this.state.text.trim()
if(!author || !text) return
this.props.onTaskSubmit({author, text})
this.setState({author: '', text: ''})
},
render(){
return (
<form className="taskForm" onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="Who are you?"
value={this.state.author}
onChange={this.handleAuthorChange}
/>
<input
type="text"
placeholder="Whaddaya got to say?"
value={this.state.text}
onChange={this.handleTextChange}
/>
<input type="submit" value="Add Task" />
</form>
)
}
})
// ReactDOM render the stuff
ReactDOM.render(
<MatrixBox />,
document.getElementById('content')
)