组件拆分

  • src/App.js ```jsx import React, { Component } from “react”; import StudentTitle from “./Components/StudentTitle”; import AddStudent from “./Components/AddStudent”; import StudentList from “./Components/StudentList”;

class App extends Component { render() { return (

); } }

export default App;

  1. - src/Components/StudentsTitle.js
  2. ```jsx
  3. import React, { Component } from "react";
  4. class AddStudent extends Component {
  5. render() {
  6. return (
  7. <div className="col-md-12">
  8. <h3 className="title">学生信息管理</h3>
  9. </div>
  10. );
  11. }
  12. }
  13. export default AddStudent;
  • src/Components/AddStudent.js ```jsx import React, { Component } from “react”;

class StudentTitle extends Component { render() { return (

); } }

export default StudentTitle;

  1. - src/Components/StudentList.js
  2. ```jsx
  3. import React, { Component } from "react";
  4. class StudentList extends Component {
  5. render() {
  6. return (
  7. <div className="col-md-6 col-md-offset-1">
  8. <table className="table table-striped table-hover">
  9. <thead>
  10. <tr>
  11. <th>学号</th>
  12. <th>姓名</th>
  13. <th>性别</th>
  14. <th>年龄</th>
  15. <th>入学时间</th>
  16. <th>爱好</th>
  17. <th>所属学院</th>
  18. <th>操作</th>
  19. </tr>
  20. </thead>
  21. <tbody>
  22. <tr>
  23. <td>01</td>
  24. <td>张三</td>
  25. <td>男</td>
  26. <td>20</td>
  27. <td>2020-08-02</td>
  28. <td>
  29. <span>足球</span>
  30. </td>
  31. <td>python</td>
  32. <td>
  33. <a>删除</a>
  34. <a>修改</a>
  35. </td>
  36. </tr>
  37. </tbody>
  38. </table>
  39. <p className="text-center">无学生信息</p>
  40. <p>总共有 50 个学生</p>
  41. <p>学生的平均年龄是 25</p>
  42. </div>
  43. );
  44. }
  45. }
  46. export default StudentList;

添加学生信息

数据绑定需更新

  • AddStudents.js ```jsx import React, { Component } from “react”;

class AddStudent extends Component { constructor() { super(); this.stateHandler = this.stateHandler.bind(this); this.hobbyHandler = this.hobbyHandler.bind(this) }

//01 定义组件中的状态 state = { number: “”, name: “”, sex: “男”, age: “”, collage: “大前端”, hobbies: [ { id: 1, title: “篮球”, isChecked: false, }, { id: 2, title: “足球”, isChecked: false, }, { id: 3, title: “网球”, isChecked: false, }, ], }; stateHandler(ev) { // 获取当前输入的值,调用 setState 更新具体的属性 const prop = ev.target.name; this.setState( {

  1. [prop]: ev.target.value,
  2. },
  3. () => {
  4. console.log(this.state);
  5. }
  6. );

} hobbyHandler(index,ev){ // 当前操作需要提前获取被操作选项的索引,事件对象 const isChecked = ev.target.checked const hobbies = […this.state.hobbies] hobbies[index].isChecked = isChecked

  1. this.setState({
  2. hobbies
  3. }, () => {console.log(this.state)})

} render() { return (

{this.state.hobbies.map((hobby,index) => { return (
); })}
); } }

export default AddStudent;

  1. <a name="ob1hD"></a>
  2. ### 提交学生信息
  3. - AddStudent.js
  4. ```jsx
  5. import React, { Component } from "react";
  6. class AddStudent extends Component {
  7. constructor() {
  8. super();
  9. this.stateHandler = this.stateHandler.bind(this);
  10. this.hobbyHandler = this.hobbyHandler.bind(this)
  11. }
  12. //01 定义组件中的状态
  13. state = {
  14. number: "",
  15. name: "",
  16. sex: "男",
  17. age: "",
  18. collage: "大前端",
  19. hobbies: [
  20. {
  21. id: 1,
  22. title: "篮球",
  23. isChecked: false,
  24. },
  25. {
  26. id: 2,
  27. title: "足球",
  28. isChecked: false,
  29. },
  30. {
  31. id: 3,
  32. title: "网球",
  33. isChecked: false,
  34. },
  35. ],
  36. };
  37. // 深拷贝一份状态 用于重置
  38. origin = JSON.parse(JSON.stringify(this.state))
  39. stateHandler(ev) {
  40. // 获取当前输入的值,调用 setState 更新具体的属性
  41. const prop = ev.target.name;
  42. this.setState(
  43. {
  44. [prop]: ev.target.value,
  45. },
  46. () => {
  47. console.log(this.state);
  48. }
  49. );
  50. }
  51. hobbyHandler(index,ev){
  52. // 当前操作需要提前获取被操作选项的索引,事件对象
  53. const isChecked = ev.target.checked
  54. const hobbies = [...this.state.hobbies]
  55. hobbies[index].isChecked = isChecked
  56. this.setState({
  57. hobbies
  58. }, () => {console.log(this.state)})
  59. }
  60. submit = (ev) => {
  61. ev.preventDefault()
  62. console.log(this.state)
  63. //提交时需要将表单里的有用信息整合在一起
  64. // 筛选出我们当前次选中的爱好
  65. const hobbies = this.state.hobbies
  66. .filter(hobby => hobby.isChecked)
  67. .map(hobby => hobby.title)
  68. // 数据组合
  69. const fromValue = {
  70. ...this.state,
  71. hobbies
  72. }
  73. console.log(fromValue)
  74. // 将当前数据利用回调传回给上层组件
  75. this.props.addStudent(fromValue, () => {
  76. // 重置
  77. this.setState(this.origin)
  78. })
  79. }
  80. render() {
  81. return (
  82. <div className="col-md-5">
  83. <form onSubmit={this.submit}>
  84. <div className="form-group">
  85. <label>学号</label>
  86. <input
  87. value={this.state.number}
  88. onChange={this.stateHandler}
  89. name={"number"}
  90. type="number"
  91. className="form-control"
  92. placeholder="请输入学号"
  93. />
  94. </div>
  95. <div className="form-group">
  96. <label>姓名</label>
  97. <input
  98. value={this.state.name}
  99. onChange={this.stateHandler}
  100. name={"name"}
  101. type="text"
  102. className="form-control"
  103. placeholder="请输入姓名"
  104. />
  105. </div>
  106. <div className="form-group">
  107. <label>性别&nbsp;&nbsp;</label>
  108. <label className="checkbox-inline">
  109. <input
  110. checked={this.state.sex === "男"}
  111. name="sex"
  112. onChange={this.stateHandler}
  113. type="radio"
  114. value="男"
  115. />
  116. </label>
  117. <label className="checkbox-inline">
  118. <input
  119. checked={this.state.sex === "女"}
  120. name="sex"
  121. onChange={this.stateHandler}
  122. type="radio"
  123. value="女"
  124. />
  125. </label>
  126. </div>
  127. <div className="form-group">
  128. <label>年龄</label>
  129. <input
  130. name={"age"}
  131. value={this.state.age}
  132. onChange={this.stateHandler}
  133. type="text"
  134. className="form-control"
  135. placeholder="请输入姓名"
  136. />
  137. </div>
  138. <div className="form-group">
  139. <label>爱好</label>
  140. {this.state.hobbies.map((hobby,index) => {
  141. return (
  142. <div className="checkbox" key={hobby.id}>
  143. <label>
  144. <input
  145. checked={hobby.isChecked}
  146. type="checkbox"
  147. value={hobby.title}
  148. onChange={(ev) => {this.hobbyHandler(index, ev)}}
  149. /> {hobby.title}
  150. </label>
  151. </div>
  152. );
  153. })}
  154. </div>
  155. <div className="form-group">
  156. <label>所属学院</label>
  157. <select
  158. name={"collage"}
  159. onChange={this.stateHandler}
  160. value={this.state.collage}
  161. className="form-control"
  162. >
  163. <option value="大前端">大前端</option>
  164. <option value="Java">Java</option>
  165. <option value="python">python</option>
  166. </select>
  167. </div>
  168. <button type="submit" className="btn btn-default">
  169. 添加
  170. </button>
  171. </form>
  172. </div>
  173. );
  174. }
  175. }
  176. export default AddStudent;
  • App.js ```jsx import React, { Component } from “react”; import StudentTitle from “./Components/StudentTitle”; import AddStudent from “./Components/AddStudent”; import StudentList from “./Components/StudentList”;

class App extends Component { // 定义状态用于管理学员信息 state = { studentList: [] } // 处理 studentList 状态 addStudent = (student, callback) => { this.setState({ studentList: […this.state.studentList, student] // 合并更新 },() => { callback() console.log(this.state.studentList) }) } render() { return (

); } }

export default App;

  1. <a name="bGtGH"></a>
  2. ## 学生信息展示
  3. - App.js
  4. ```jsx
  5. <StudentList studentList={this.state.studentList} />
  • StudentList.js ```jsx import React, { Component } from “react”;

class StudentList extends Component { render() { // 解构出学生信息数据 const { studentList } = this.props; return (

{studentList.map((student) => { return ( ); })}
学号 姓名 性别 年龄 爱好 所属学院 操作
{student.number} {student.name} {student.sex} {student.age} { student.hobbies.map(hobby => { return ( {hobby} ) }) } {student.collage} 删除 修改

无学生信息

总共有 50 个学生

学生的平均年龄是 25

); } }

export default StudentList;

  1. <a name="dawer"></a>
  2. ## 学生信息删除
  3. - StudentList.js
  4. ```jsx
  5. import React, { Component } from "react";
  6. class StudentList extends Component {
  7. // 删除
  8. rmStudent = (index, ev) => {
  9. ev.preventDefault()
  10. if(window.confirm('是否确定删除当前项')){
  11. this.props.removeStudent(index)
  12. }
  13. }
  14. render() {
  15. // 解构出学生信息数据
  16. const { studentList } = this.props;
  17. return (
  18. <div className="col-md-6 col-md-offset-1">
  19. <table className="table table-striped table-hover">
  20. <thead>
  21. <tr>
  22. <th>学号</th>
  23. <th>姓名</th>
  24. <th>性别</th>
  25. <th>年龄</th>
  26. <th>爱好</th>
  27. <th>所属学院</th>
  28. <th>操作</th>
  29. </tr>
  30. </thead>
  31. <tbody>
  32. {studentList.map((student) => {
  33. return (
  34. <tr key={student.number}>
  35. <td>{student.number}</td>
  36. <td>{student.name}</td>
  37. <td>{student.sex}</td>
  38. <td>{student.age}</td>
  39. <td>
  40. {
  41. student.hobbies.map(hobby => {
  42. return (
  43. <span key={hobby}>{hobby} </span>
  44. )
  45. })
  46. }
  47. </td>
  48. <td>{student.collage}</td>
  49. <td>
  50. <button onClick={(ev) => {this.rmStudent(student.number,ev)}}>删除</button>
  51. </td>
  52. </tr>
  53. );
  54. })}
  55. </tbody>
  56. </table>
  57. <p className="text-center">无学生信息</p>
  58. <p>总共有 50 个学生</p>
  59. <p>学生的平均年龄是 25</p>
  60. </div>
  61. );
  62. }
  63. }
  64. export default StudentList;
  • App.js ```jsx import React, { Component } from “react”; import StudentTitle from “./Components/StudentTitle”; import AddStudent from “./Components/AddStudent”; import StudentList from “./Components/StudentList”;

class App extends Component { // 定义状态用于管理学员信息 state = { studentList: [ { number: “01”, name: “张三”, sex: “男”, age: 10, date: “2020-12-04”, hobbies: [“足球”, “篮球”], collage: “大前端”, }, { number: “02”, name: “李四”, sex: “男”, age: 20, date: “2030-12-05”, hobbies: [“足球”, “橄榄球”], collage: “Java”, }, { number: “03”, name: “王五”, sex: “男”, age: 30, date: “2040-11-03”, hobbies: [“足球”, “橄榄球”, “篮球”], collage: “python”, }, ], }; // 处理 studentList 状态

// 删除学生信息 removeStudent = (number) => { // 利用 number 找到 studentList 中需要删除的项,并删除当前项 // 将处理后的数据重新 setState 给 state,更新视图

  1. // 深拷贝原数据
  2. const studentList = JSON.parse(JSON.stringify(this.state.studentList))
  3. // 查找 number 对应项
  4. const index = studentList.findIndex(student => student.number === number)
  5. // 删除
  6. studentList.splice(index, 1)
  7. // 更新
  8. this.setState({
  9. studentList
  10. })

} render() { return (

); } }

export default App;

  1. <a name="HedYQ"></a>
  2. ## 计算平均值
  3. - StudentList.js
  4. ```jsx
  5. import React, { Component } from "react";
  6. class StudentList extends Component {
  7. // 删除
  8. render() {
  9. // 解构出学生信息数据
  10. const { studentList } = this.props;
  11. // 总年龄之和
  12. let totalAge = 0
  13. studentList.forEach(hobby => totalAge += Number(hobby.age))
  14. // 平均年龄
  15. let averAge = 0
  16. averAge = Math.floor(totalAge / studentList.length)
  17. return (
  18. <div className="col-md-6 col-md-offset-1">
  19. { studentList.length > 0 ? null : <p className="text-center">无学生信息</p>}
  20. <p>总共有 {studentList.length} 个学生</p>
  21. <p>学生的平均年龄是 {averAge}</p>
  22. </div>
  23. );
  24. }
  25. }
  26. export default StudentList;