我只是创建一个包含搜索和编辑功能的表格。我的解决方案有一个问题,搜索无法正常工作。但如果我从DisplayTable类中删除<EditableCell id={person.id} data={person.name} />
这一行,搜索功能将起作用,但编辑功能代码将写入该类。我不知道如何解决这个问题。
/**
* @jsx React.DOM
*/
//Making the main component, InstantBox
var InstantBox = React.createClass({
doSearch:function(queryText)
{
console.log(queryText)
//get query result
var queryResult=[];
this.props.data.forEach(function(person)
{
if(person.name.toLowerCase().indexOf(queryText)!=-1)
queryResult.push(person);
});
this.setState({ query:queryText, data:queryResult })
},
handleClick: function() {
this.setState({ showResults: true });
},
getInitialState:function(){
return{data:this.props.data,showResults: false}
},
onChangeName:function(e){
this.setState({name:e.target.value})
},
onChangePhone:function(e){
this.setState({phone:e.target.value})
},
onChangeEmail:function(e){
this.setState({email:e.target.value})
},
handleSubmit:function(e){
if(this.state.name==null){
alert("Data cannot be added without name");
}else{
this.setState({ showResults: false });
e.preventDefault();
this.state.data.push({name:this.state.name,phone:this.state.phone,email:this.state.email});
this.setState({name:'',phone:'',email:''})
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert( xmlhttp.responseText);
}
}
xmlhttp.open("GET", "insert.php?n=" +
this.state.name+"&p="+this.state.phone+"&e="+this.state.email, true);
xmlhttp.send();
}
},
render:function(){
return (
<div id="wrapper">
<div className="InstantBox" >
<h3 className="head">Contact List</h3>
<label> search </label>
<SearchBox query={this.state.query} doSearch={this.doSearch}/>
<EditableCell id={this.state.query} />
<label> </label>
<input type="submit" value="ADD" onClick={this.handleClick} />
<p></p>
<DisplayTable data={this.state.data}/>
</div>
<div >
{ this.state.showResults ?
<Results onChangeName={this.onChangeName}
onChangePhone={this.onChangePhone}
onChangeEmail={this.onChangeEmail}
handleSubmit={this.handleSubmit} />
: null }
</div>
</div>
);
}
});
var Results = React.createClass({
render: function() {
return (
<div id="results" className="search-results">
<form onSubmit={this.props.handleSubmit}>
<table className="addform">
<thead>
<tr> <th>Add New Contact</th> </tr>
<tr><th><input type="text" placeholder="Name" value={this.name}onChange=
{this.props.onChangeName}/></th> </tr>
<tr><th><input type="text" placeholder="Phone" value={this.props.phone}onChange=
{this.props.onChangePhone}/></th> </tr>
<tr><th><input type="text" placeholder="Email Name" value={this.props.email}onChange=
{this.props.onChangeEmail}/></th> </tr>
<tr><th><button >SAVE</button></th>
</tr>
</thead>
</table>
</form>
</div>
);
},
});
var SearchBox = React.createClass({
doSearch:function(){
var query=this.refs.searchInput.getDOMNode().value; // this is the search text
this.props.doSearch(query);
},
render:function(){
return <input type="text" ref="searchInput" placeholder="Search Name" value=
{this.props.query} onChange={this.doSearch}/>
}
});
var EditableCell = React.createClass({
getInitialState: function () {
return {
isEditMode: false,
data: ""
};
},
componentWillMount: function () {
this.setState({
isEditMode: this.props.isEditMode,
data: this.props.data
});
},
handleEditCell: function (evt) {
this.setState({isEditMode: true});
},
handleKeyDown: function (evt) {
switch (evt.keyCode) {
case 13: // Enter
case 9: // Tab
this.setState({isEditMode: false});
break;
}
if(evt.keyCode==13){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert( xmlhttp.responseText);
}
}
xmlhttp.open("GET", "update.php?n=" + this.state.data+"&i="+this.props.id, true);
xmlhttp.send();
}
},
handleChange: function (evt) {
this.setState({data: evt.target.value});
},
render: function () {
var cellHtml;
var current_data;
var counter=0;
//alert(this.props.data);
if (this.state.isEditMode) {
cellHtml = <input type='text' value={this.state.data}
onKeyDown={this.handleKeyDown} onChange={this.handleChange} />
}
else {
cellHtml = <div onClick={this.handleEditCell}>{this.state.data}</div>
}
return (
<td>{cellHtml}</td>
);
}
});
var DisplayTable = React.createClass({
render:function(){
//making the rows to display
var rows=[];
this.props.data.forEach(function(person)
{
rows.push(<tr >
<EditableCell id={person.id} data={person.name} />
<td><a href="url">Phone</a></td>
<td><a href="url">email</a></td></tr>
)
}.bind(this));
//returning the table
return(
<table className="tableFormt">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Email</th>
</tr>
</thead>
<tbody>{rows}
</tbody>
</table>
);
}
});
React.renderComponent( <InstantBox data={result} id={result} /> ,document.body);
答案 0 :(得分:0)
您的问题有两种可能的解决方案:
1)将密钥属性传递给EditableCell
组件:
<EditableCell id={person.id} data={person.name} key={person.name}/>
2)在componentWillReceiveProps
组件中实施EditableCell
:
componentWillReceiveProps: function(nextProps){
this.setState({"data":nextProps.data});
},
在当前代码中,在第一个渲染中,正在渲染两行。当你过滤结果时,第一个EditableCell被传递&#34; Esther&#34;作为数据属性但未设置状态。您在componentDidMount函数中仅设置状态。所以Henrik仍然存在。第二行未呈现,因为只有1个结果。
阅读和解也可能有所帮助:http://facebook.github.io/react/docs/reconciliation.html#problematic-case