Javascript 将可编辑单元格的渲染委托给新的EditableCell组件

Javascript 将可编辑单元格的渲染委托给新的EditableCell组件,javascript,reactjs,Javascript,Reactjs,我正在为班级做一个项目,我们必须使用java脚本中的react组件创建一个成绩表 我已经使用以下代码成功地创建了表 export default class GradesTable extends React.Component { constructor(props) { super(props); } render() { const gradesTable = this.renderTable(); //must have key retur

我正在为班级做一个项目,我们必须使用java脚本中的react组件创建一个成绩表

我已经使用以下代码成功地创建了表

export default class GradesTable extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const gradesTable = this.renderTable(); //must have key
    
    return [
      <h2 key="name">{this.props.courseGrades.courseInfo.name}</h2>,
      <Errors key="err" errors={this.props.errors}/>,
      <table className="grades" key="gradeTable">{gradesTable}</table>
    ];
  }

  renderTable() {
    //sorting statGrades
    let sortedGrades = [];
    sortedGrades = Array.from(this.props.courseGrades.statGrades).sort(cmpEmailIdFn);
    let colId = this.props.courseGrades.sortedColIds;
        
        //array to hold header data
        let header = [];
        //array to hold row data
        let rowData = [];
        //array to hold all rows
        let row = [];
        //initalize header row and push to row array
        for(let i = 0; i < colId.length; i++){
            header.push(<th key={colId[i]}>{colId[i]}</th>);
        }
        row.push(<tr key="header">{header}</tr>);
        
        let areEditable = new Set([1,2,3]);
        areEditable.clear();
        
        //loop through data and construct the row data pushing each row to the row array
        for(let i = 0; i < sortedGrades.length; i++){
            rowData = [];
            for(let j = 0; j < colId.length; j++){
            //if cell is editable insert an input element else insert static data
                if(j >= 3 && j <= 17 && sortedGrades[i][colId[0]] === "" && this.props.isEditable){
                    areEditable.add(sortedGrades[i][colId[j]]);
                    if(sortedGrades[i][colId[j]] === ""){
                        rowData.push(<td key={colId[j]}><input value={sortedGrades[i][colId[j]]} onChange={this.props.onChange}></input></td>));
                    }else{
                        rowData.push(<td key={colId[j]}><input value={sortedGrades[i][colId[j]]} onChange={this.props.onChange}></input></td>);
                    }
                } else{
                        if(sortedGrades[i][colId[j]] === ""){
                            rowData.push(<td key={colId[j]}></td>);
                        }else{
                            rowData.push(<td key={colId[j]}>{sortedGrades[i][colId[j]]}</td>);
                        }
                    }   
            }
            if(sortedGrades[i][colId[1]] != "" && sortedGrades[i][colId[0]] == ""){
                row.push(<tr key={sortedGrades[i][colId[1]]}>{rowData}</tr>);
            }
            else {
            row.push(<tr key={sortedGrades[i][colId[0]]}>{rowData}</tr>);
            }
        }
        //push the row array to a tbody array and return tbody
        let tbody = [];
        tbody.push(<tbody key="tbody">{row}</tbody>);
        return tbody;
  }

}
导出默认类GradesTable.Component{
建造师(道具){
超级(道具);
}
render(){
const gradesTable=this.renderTable();//必须具有密钥
返回[
{this.props.courseGrades.courseInfo.name},
,
{gradesTable}
];
}
可渲染的(){
//分类statGrades
让sortedGrades=[];
sortedGrades=Array.from(this.props.courseGrades.statGrades.sort(cmpemaildfn));
让colId=this.props.courseGrades.sortedclids;
//用于保存头数据的数组
让标题=[];
//用于保存行数据的数组
让rowData=[];
//数组以容纳所有行
设row=[];
//初始化标题行并推送到行数组
for(设i=0;i如果(j>=3&&j状态应该位于树的更高位置,而不是使用它的组件。因此,如果您需要创建一个单独的组件来保存状态,该组件应该包含GradesTable。包含该组件的组件(称为GradesContainer)可以具有状态,并且可以向GradesTable传递一个函数来设置状态。

有几种方法可以挂起两个组件所属的层

如果表和输入在层次结构中彼此接近,可以按以下方式执行

// Parent.js
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ""
    };
  }

  handleInputChange(emailId, colId, value) {
    // also do something about the emailId and ColId
    this.setState({ value });
  };

  render() {
    return (
      <Fragment>
        <Table value={this.state.value} />
        <Input value={this.state.value} onChange={handleInputChange} />
      </Fragment>
    );
  }
}
//Parent.js
类父级扩展组件{
建造师(道具){
超级(道具);
此.state={
值:“”
};
}
handleInputChange(电子邮件ID、colId、值){
//还要对emailId和ColId做些什么
this.setState({value});
};
render(){
返回(
);
}
}
//Input.js
类输入扩展组件{
手变(活动){
//将emailId和ColId传递给函数
this.props.handleInputChange(emailId、colId、event.target.value);
}
render(){
返回(
);
}
}
但是,如果它们远离彼此,那么你应该考虑使用像OR那样的状态管理库。它们所做的基本上是创建全局“存储”(S),并允许你在全局上保存状态,以便所有组件都可以在任何层访问它们(不要滥用它,如果你可以用本地状态来处理它,而是使用本地状态)。

// Parent.js
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ""
    };
  }

  handleInputChange(emailId, colId, value) {
    // also do something about the emailId and ColId
    this.setState({ value });
  };

  render() {
    return (
      <Fragment>
        <Table value={this.state.value} />
        <Input value={this.state.value} onChange={handleInputChange} />
      </Fragment>
    );
  }
}
// Input.js
class Input extends Component {
  handleChange(event) {
    // pass the emailId and ColId to the function
    this.props.handleInputChange(emailId, colId, event.target.value);
  }

  render() {
    return (
      <input
        value={this.props.value}
        onChange={this.handleChange}
      />
    );
  }
}