我正在使用react js编写一个简单的待办事项列表。应用程序将一些操作组合到操作列表中。 类的结构看起来像这样:
应用
--- GroupOfActions
------ ListOfActionsRow
------ ActionRow
全局var动作中的所有数据存储看起来像(它是一个全局var):
var actions = [{list:' some list',color:'#79fa5f',name:' some 行动',优先:' 0',完成:真}}
当用户更改操作名称或列表名称时,应在"操作"中更改。在DOM中。我可以在" action"中更改它,但在DOM中更改它的最佳模式是什么? 现在我正在使用道具。这是我的代码的一部分:
class App extends React.Component {
constructor(props){
super(props);
actions=[];
//parsing actions from localStorage
}
render() {
return(
<GroupOfActions actions={actions} />
);
}
}
class GroupOfActions extends React.Component {
render (){
var rows=[];
var lastList=null;
this.props.actions.forEach(function(action){
if (action.list!==lastList){
rows.push(<ListOfActionsRow list={action.list} key={action.list} color={action.color} />);
}
rows.push(<ActionRow action={action} color={action.color} list={action.list} key={action.name} />);
lastList=action.list;
});
return(
<div className="container" >
{rows}
</div>
);
}
}
class ActionRow extends React.Component {
onNameChange(){
var targetAction=JSON.parse(JSON.stringify('{\"list\":\"'+
this.props.list+
'\",\"color\":\"'+
this.props.color+
'\",\"name\":\"'+
this.props.action.name+
'\",\"priority\":\"'+
this.props.action.priority+
'\",\"done\":'+
this.props.action.done+
'}'));
console.log(targetAction);
console.log(JSON.stringify(actions));
var toDoList=JSON.stringify(actions);
var startIndex=toDoList.indexOf(targetAction);
var endIndex=startIndex+targetAction.length;
if (startIndex>-1){
var nameStartIndex=targetAction.indexOf('\",\"name\":\"');
var nameEndIndex=targetAction.indexOf('\",\"priority\":\"');
toDoList=toDoList.substring(0,startIndex)
+toDoList.substring(startIndex,(nameStartIndex+11))
+this.refs.newName.value
+toDoList.substring(nameEndIndex+1);
console.log(toDoList);
localStorage.setItem('toDoList',toDoList);
actions=JSON.parse(localStorage.getItem('toDoList'));
console.log(actions);
this.props.action.name=this.refs.newName.value;
} else {console.log(startIndex);}
}
render () {
return (
<div>
<div className={'row '+(this.state.edition?'hidden':'')} >
<div className="col-md-3" ref='oldName' onClick={this.editActionRow}>{this.props.action.name}</div>
<div className="col-md-1" onClick={this.editActionRow} style={{width:'20%'}}>{this.props.action.priority}</div>
<div className="col-md-1" onClick={this.editActionRow}><input type='checkbox' ref='oldDone' checked={this.props.action.done} /></div>
</div>
<div className={'row '+(this.state.edition?'':'hidden')}>
<div className="col-md-6" onClick={this.editActionRow} style={{backgroundColor:'#fafafa'}}>
<input type='text' ref='newName' defaultValue={this.props.action.name} onChange={this.onNameChange} />
<label>Priority</label>
<select defaultValue={this.props.action.priority} onChange={this.onPriorityChange} ref='newPriority'>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<label>Done</label>
<input type='checkbox' defaultChecked={this.props.action.done} ref='newDone' onChange={this.onDoneChange} />
</div>
</div>
</div>
)
}
}
class ListOfActionsRow extends React.Component {
onNameOfListChange() {
var oldNameOfList=this.props.list;
var newNameOfList=this.refs.newNameOfList.value;
var toDoList=JSON.stringify(actions);
var newToDoList;
for (var i=0;i<toDoList.length;i++) {
var nameIndex=toDoList.indexOf(oldNameOfList,i);
if (nameIndex==-1) continue;
i=nameIndex;
var nameEndIndex=nameIndex+oldNameOfList.length;
newToDoList=toDoList.substring(0,nameIndex)
+newNameOfList
+toDoList.substring(nameEndIndex);
}
console.log(newToDoList);
localStorage.setItem('toDoList',newToDoList);
actions=JSON.parse(localStorage.getItem('toDoList'));
console.log(actions);
this.props.list=this.refs.newNameOfList.value;
}
render() {
return (
<div>
<div className={'row '+(this.state.editionOfList?'hidden':'')} >
<div className="col-md-6" onClick={this.editListRow} >
<div className="well well-small lead" style={{backgroundColor:'{this.props.color}'}} style={{marginTop:'20px'}} ref='oldNameOfList'>
{this.props.list}
</div>
</div>
</div>
<div className={'row '+(this.state.editionOfList?'':'hidden')} >
<div className="col-md-6" >
<div className="well well-small lead" onClick={this.editListRow} style={{backgroundColor:'#fafafa'}}>
<input type='text' ref='newNameOfList' defaultValue={this.props.list} onChange={this.onNameOfListChange} />
<label>Color</label>
<select>
<option value="0">Yellow</option>
<option value="1">Blue</option>
<option value="2">Green</option>
</select>
</div>
</div>
</div>
<div className="row" style={{marginBottom:'20px'}}>
<div className="col-md-2">
</div>
</div>
);
}
}
&#13;
在ActionRow行中
this.props.action.name=this.refs.newName.value;
&#13;
工作正确。在ListOfActionRow中,类似的行会出错:
this.props.list=this.refs.newNameOfList.value;
&#13;
在这种情况下可能会使用道具是反模式的吗?为什么同一个命令在一个案例中起作用但在另一个案例中不起作用?
答案 0 :(得分:1)
它不是改变像this.props.action.name=this.refs.newName.value;
这样的道具的正确方法,理想的方法是将一个函数从父组件传递给子组件,并从子组件调用它在父组件中设置一个值然后传递给孩子
同样,React DOCS建议对callback
使用refs
方法而不是字符串方法
例如,在App组件中创建一个更改列表名称的函数
class App extends React.Component {
constructor(props){
super(props);
actions=[];
//parsing actions from localStorage
}
changeListName = (val) => {
/// take action here
}
render() {
return(
<GroupOfActions actions={actions} changeListName = {(val) => {this.changeListName}}/>
);
}
}
class GroupOfActions extends React.Component {
render (){
var rows=[];
var lastList=null;
this.props.actions.forEach((action) =>{
if (action.list!==lastList){
rows.push(<ListOfActionsRow list={action.list} key={action.list} color={action.color} changeListName={(val) => this.props.changeListName(val)}/>);
}
rows.push(<ActionRow action={action} color={action.color} list={action.list} key={action.name} />);
lastList=action.list;
});
return(
<div className="container" >
{rows}
</div>
);
}
}
class ListOfActionsRow extends React.Component {
onNameOfListChange() {
var oldNameOfList=this.props.list;
var newNameOfList=this.refs.newNameOfList.value;
var toDoList=JSON.stringify(actions);
var newToDoList;
for (var i=0;i<toDoList.length;i++) {
var nameIndex=toDoList.indexOf(oldNameOfList,i);
if (nameIndex==-1) continue;
i=nameIndex;
var nameEndIndex=nameIndex+oldNameOfList.length;
newToDoList=toDoList.substring(0,nameIndex)
+newNameOfList
+toDoList.substring(nameEndIndex);
}
console.log(newToDoList);
localStorage.setItem('toDoList',newToDoList);
actions=JSON.parse(localStorage.getItem('toDoList'));
console.log(actions);
this.props.changeListName(this.newNameOfList.value);
}
render() {
return (
<div>
<div className={'row '+(this.state.editionOfList?'hidden':'')} >
<div className="col-md-6" onClick={this.editListRow} >
<div className="well well-small lead" style={{backgroundColor:'{this.props.color}'}} style={{marginTop:'20px'}} ref={(list) => {this.oldNameOfList}}>
{this.props.list}
</div>
</div>
</div>
<div className={'row '+(this.state.editionOfList?'':'hidden')} >
<div className="col-md-6" >
<div className="well well-small lead" onClick={this.editListRow} style={{backgroundColor:'#fafafa'}}>
<input type='text' ref={(list) => {this.newNameOfList}} defaultValue={this.props.list} onChange={this.onNameOfListChange} />
<label>Color</label>
<select>
<option value="0">Yellow</option>
<option value="1">Blue</option>
<option value="2">Green</option>
</select>
</div>
</div>
</div>
<div className="row" style={{marginBottom:'20px'}}>
<div className="col-md-2">
</div>
</div>
);
}
}