一、状态值 state
state 用于管理组件内部的数据和状态,类似于 vue 中 data 的概念。
在 vue 中,会对每一个属性都设置监听,实时的监听属性的变化并且刷新 DOM,而如果属性过多就自动生成很多监听器,容易造成负载大、性能下降等问题;
在 React 中就没有自动监听器这个概念,而是提供了状态值 state,通过设置 setState 来存储和管理属性的变化。基本语法如下:
state = {num:1} this.state //获取属性值 this.setState //更新设置数据,会刷新DOM
举例:设置属性 state,通过 setState 来修改属性 state;
//rcc 快捷生成类组件 //rfc 快捷生成函数组件 import React, { Component } from "react"; export default class App extends Component { state = { num: 1 }; // 每次点击按钮,state中的num值+1 doAdd() { // sst 快捷生成setState(更新state) this.setState({ num: this.state.num + 1 }); } render() { return ( <div> <button onClick={this.doAdd.bind(this)}>{this.state.num}</button> </div> ); } }
setState 可用来刷新 DOM,需要注意在方法中 setState 语法 this.setState({}); 必须要写,否则变量在程序中会变化,但页面中不会渲染;
import React, { Component } from "react"; export default class App1 extends Component { // 成员属性 num = 1; doAdd() { this.num++; // 只有执行以下代码才能渲染DON(react不会自动渲染,只能由我们手动渲染;Vue则会自动渲染) // sst this.setState({}); } render() { return ( <div> <button onClick={this.doAdd.bind(this)}>{this.num}</button> </div> ); } }
setState 具有异步性,在 setState 语法中有两个参数,第一个为需要修改的 state 属性,第二个是回调方法( DOM 渲染后执行);
import React, { Component } from "react"; export default class App extends Component { state = { num: 1 }; doAdd() { // setState // 参数1:需要修改设置的state属性 // 参数2:回调方法,DOM渲染完成后触发 this.setState({ num: 8 }, () => { console.log("页面渲染完毕的num:", this.state.num); }); console.log("初始时的num:", this.state.num); } render() { return ( <div> <button onClick={this.doAdd.bind(this)}>{this.state.num}</button> </div> ); } }
二、样式
在 src 下的 App.js 中引入 css 文件用到的是 import,需要注意 import 默认是引入模块,当引入文件时需要指定文件路径;
举例:动态绑定样式,调用方法使 div 的尺寸递增;
/*App.css中*/ .danger { background-color: red; width: 200px; color: white; border-radius: 10px; padding: 10px; } .success { background-color: green; width: 200px; color: white; border-radius: 10px; padding: 10px; } .warning { background-color: orange; width: 200px; color: white; border-radius: 10px; padding: 10px; }
//App.js中 // 动态绑定样式 import React, { Component } from "react"; // 引入CSS文件 // import默认是引入模块,当引入文件时需要指定文件路径 import "./App.css"; export default class App extends Component { size = 18; doBig() { // 递增 this.size++; // 通过sst刷新DOM,使页面刷新(React不会自动渲染,该语句必须写) this.setState({}); } render() { return ( <div> <button onClick={this.doBig.bind(this)}>点击变大</button> {/* style的使用:内部嵌入样式 */} <div style={{ color: "red", border: "1px solid blue", fontSize: this.size, }} > Hello React! </div> <hr /> {/* class的使用:调用其他文件的css样式 */} <div className="danger">前端小马</div> <hr /> {/* 动态绑定样式 */} <div className={this.size > 22 ? "success" : "danger"}>前端小马哥</div> <hr /> {/* 注意:调用函数时要加括号,要求立即执行;调用事件则不用加括号 */} <div className={this.showClass()}>小马学前端</div> </div> ); } showClass() { if (this.size < 22) return "success"; if (this.size > 25) return "danger"; return "warning"; } }
JSX 语法注释格式: {/* 注释内容 */}
三、图片的使用
在App.js中可引入远程和本地的图片;具体引入方式如下代码:
import React, { Component } from "react"; // 导入图片 import imgURL from "./assets/2.jpg" export default class App extends Component { render() { return ( <div> {/* 远程图片资源 */} <img src="https://csdnimg.cn/medal/chaoji1024@240.png" /> {/* 本地图片资源 */} {/* 图片在public目录下,直接引入 */} <img src="/logo192.png" /> {/* 图片在src/assets目录下,assets目录手动创建 */} {/* 用法1:通过require引入(注意需要添加default后缀) */} <img src={require("./assets/2.jpg").default} /> {/* 用法2:先用import导入图片,再使用 */} <img src={imgURL} /> </div> ); } }
四、双向绑定(表单元素)
如果需要获取表单输入框所收集到的信息,就要实现双向绑定;单向绑定是指将数据显示在页面组件上,双向绑定既能将程序中的变量自动同步到页面上显示,又能将页面上用户主动修改的新值自动更新回程序中的变量保存。
// 数据双向绑定 import React, { Component } from "react"; export default class App extends Component { state = { uname: "web前端" }; render() { return ( <div> <input type="text" value={this.state.uname} onChange={this._unameChanged} /> <div>{this.state.uname}</div> {/* 如果代码较为简单,可以将事件处理方法直接到JSX语句当中(简化) */} <input type="text" value={this.state.uname} onChange={(e) => this.setState({ uname: e.target.value })} /> </div> ); } // 组件的事件处理方法 _unameChanged = (e) => { console.log(e); // 获取input中的value值,修改state中的值 this.setState({ uname: e.target.value }); }; }
五、条件渲染
举例:点击加减按钮将分数属性 store 进行 +10(-10) 操作,并判断该分数满足哪种条件;
// 条件渲染 import React, { Component } from "react"; export default class App extends Component { score = 60; render() { return ( <div> <h4> 得分: {this.score} </h4>{" "} <button disabled={this.score >= 100} onClick={this._changeScore.bind(this, +10)} > 加10分 </button> <button disabled={this.score <= 0} onClick={this._changeScore.bind(this, -10)} > 减10分 </button> {/* 分数显示: >90 优秀 80-90 良好 >60 及格 <60 不及格 */} {this.show()} </div> ); } _changeScore(num) { this.score += num; console.log(this.score); // 手动刷新DOM this.setState({}); } show() { if (this.score > 90) return <div>优秀!</div>; if (this.score <= 90 && this.score > 80) return <div>良好!</div>; if (this.score < 60) return <div>不及格!</div>; return <div>及格!</div>; } }
六、列表渲染
1.数组
举例: 将一个数组中的元素渲染为一组按钮和一组列表;
// 列表渲染 import React, { Component } from "react"; export default class App extends Component { skills = ["HTML", "CSS", "JavaScript", "Node", "vue", "react"]; // 渲染一组button showBtns() { // 1.创建空数组 let arr = []; // 2.遍历skill数组,将每一项包裹在button标签中 this.skills.forEach((item, index) => { let tmp = ( <button style={{ marginLeft: "10px" }} key={index}> {item} </button> ); arr.push(tmp); }); // 3.返回重新构建的button数组 return arr; } // 渲染一组li标签 showList() { let arr = []; this.skills.forEach((item, index) => { let tmp = <li key={index}>{item}</li>; arr.push(tmp); }); return arr; } render() { return ( <div> {this.skills} <div>{this.showBtns()}</div> <div> <ul>{this.showList()}</ul> </div> </div> ); } }
2.对象数组
举例:将一个对象数组(一个数组中包含多个对象元素)中的元素渲染在一个表格中;
import React, { Component } from "react"; export default class App extends Component { heros = [ { name: "诸葛亮", job: "法师", price: "18888" }, { name: "马可波罗", job: "射手", price: "18888" }, { name: "韩信", job: "刺客", price: "13888" }, { name: "刘禅", job: "辅助", price: "6888" }, { name: "马超", job: "战士", price: "18888" }, ]; showTable() { // 1.创建一个空数组 let arr = []; // 2.遍历 this.heros.forEach((item, index) => { arr.push( <tr key={index} style={this.showColor(index + 1)}> <td>{item.name}</td> <td>{item.job}</td> <td>{item.price}</td> </tr> ); }); // 3.返回拼接好的数组 return arr; } // 隔行变色 showColor(index) { if (index % 2 === 0) { return { backgroundColor: "gray" }; } } render() { return ( <div> <table border="1"> <thead> <tr> <th>姓名</th> <th>职业</th> <th>价格</th> </tr> </thead> <tbody>{this.showTable()}</tbody> </table> </div> ); } }