免费自建网站,科技局网站查新怎么做,外贸 wordpress,域名注册报备1.目标
能够使用函数创建组件 能够使用class创建组件 能够给React元素绑定事件 能够使用state和setState() 能够处理事件中的this指向问题 能够使用受控组件方式处理表单
2.目录
React组件介绍 React组件的两种创建方式 React事件处理 有状态组件和无状态组件 组件中的state…1.目标
能够使用函数创建组件 能够使用class创建组件 能够给React元素绑定事件 能够使用state和setState() 能够处理事件中的this指向问题 能够使用受控组件方式处理表单
2.目录
React组件介绍 React组件的两种创建方式 React事件处理 有状态组件和无状态组件 组件中的state和setState() 事件绑定this指向 表单处理
3.react组件介绍
组件是React的一等公民使用React就是在用组件 组件表示页面中的部分功能 组合多个组件实现完整的页面功能 特点可复用、独立、可组合
4.react组件的两种创建方式
A. 使用函数创建组件 B. 使用类创建组件
4.1 使用函数创建组件
A. 函数组件使用JS的函数或箭头函数创建的组件 B. 约定1函数名称必须以大写字母开头 C. 约定2函数组件必须有返回值表示该组件的结构 D. 如果返回值为null,表示不渲染任何内容
function Hello(){
return (
div这是我的第一个函数组件/div
)
}A. 渲染函数组件用函数名作为组件标签名 B. 组件标签可以是单标签也可以是双标签
ReactDOM.render(Hello/Hello,document.getElementById(root))4.2 使用类创建组件
A. 类组件使用ES6的class创建的组件 B. 约定1类名称也必须以大写字母开头 C. 约定2类组件必须继承React.Component父类从而可以使用父类中提供的方法或属性 D. 约定3类组件必须提供render()方法 E. 约定4render()方法必须有返回值表示该组件的结构
class Hello1 extends React.Component{
render(){
return (
div
我是一个类组件
/div
)
}
}
ReactDOM.render(Hello1 /,document.getElementById(root))4.3 抽离为单独JS文件
A. 思考项目中的组件多了之后该如何组织这些组件呢 B. 选择一将所有组件放在同一个JS文件中 C. 选择二将每个组件放到单独的JS文件中 D. 组件作为一个独立的个体一般都会放到一个单独的JS文件中 E. 抽离步骤 \1. 创建Hello.js \2. 在Hello.js中导入React \3. 创建组件函数或类 \4. 在Hello.js中导出该组件 \5. 在index.js中导入Hello组件 \6. 渲染组件
5.React事件处理
\1. 事件绑定 \2. 事件对象
5.1 事件绑定
A. React事件绑定语法与DM事件语法相似 B. 语法on事件名称[事件处理程序]比如onClick{(){}} C. 注意React事件采取驼峰命名法比如onMouseEnter、onFocus D. 在函数组件绑定事件 Index.js(函数事件绑定)
// 函数组件事件绑定
function Hello() {function clickHandle() {console.log(函数事件触发了);}return button onClick{clickHandle}点击触发函数事件/button;
}ReactDOM.createRoot(document.getElementById(root)).render(Hello/Hello);index.js(类事件绑定)
// 类事件绑定
class Hello2 extends React.Component {clickHandle() {console.log(类事件触发了);}render() {return button onClick{this.clickHandle}点击触发类事件/button;}
}ReactDOM.createRoot(document.getElementById(root)).render(Hello2/Hello2);区别
5.2 事件对象
A. 可以通过事件处理程序的参数获取到事件对象 B. React中的事件对象叫做合成事件对象 C. 合成事件兼容所有浏览器无需担心跨浏览器兼容性问题
// 事件对象
class App extends React.Component {clickHandel(e) {// 阻止浏览器默认行为e.preventDefault();console.log(点击事件触发了);}render() {return (a hrefhttps://www.baidu.com onClick{this.clickHandel}百度/a);}
}ReactDOM.createRoot(document.getElementById(root)).render(App/App);6.有状态组件和无状态组件
A. 函数组件又叫做无状态组件类组件又叫做有状态组件 B. 状态state即数据 C. 函数组件没有自己的状态只负责数据展示静 D. 类组件有自己的状态负责更新UI,让页面”动”起来 比如计算器案例中点击按钮让数值加1。0和1就是不同时刻的状态而由0变为1就表示状态发生了变 化。状态变化后UI也要相应的更新。React中想要实现该功能就要使用有状态组件来完成。
7.组件中的state和setState
A. state的基本使用 B. setState()修改状态
7.1 state的基本使用
A. 状态state即数据是组件内部的私有数据只能在组件内部使用 B. state的值是对象表示一个组件中可以有多个数据 C. 状态即数据 D. 状态是私有的只能在组件内部使用 E. 通过this.state来获取状态
// 有状态组件
class Hello3 extends React.Component {constructor() {super(); // 必须写}state {count: 0,};render() {return (div有状态组件h1计数器{this.state.count}/h1/div);}
}ReactDOM.createRoot(document.getElementById(root)).render(Hello3/Hello3);7.2 setState()修改状态
A. 状态是可变的 B. 语法this.setState({要修改的数据}) C. 注意不要直接修改state中的值这是错误的 D. setState()作用1.修改state 2.更新UI E. 思想数据驱动视图
// 有状态组件
class Hello3 extends React.Component {constructor() {super(); // 必须写}state {count: 0,};render() {return (div有状态组件h1计数器{this.state.count}/h1buttononClick{() {this.setState({ count: this.state.count 1 });}}1/button/div);}
}ReactDOM.createRoot(document.getElementById(root)).render(Hello3/Hello3);7.3 从JSX中抽离事件处理程序
A. JSX中掺杂过多JS逻辑代码会显得非常混乱 B. 推荐将逻辑抽离到单据的方法中保证JSX结构清晰
// 有状态组件
class Hello3 extends React.Component {constructor() {super(); // 必须写}state {count: 0,};onIncrement() { console.log(this, 抽离出来的this);this.setState({count: this.state.count 2,});}render() {return (div有状态组件h1计数器{this.state.count}/h1buttononClick{() {console.log(this, 函数式事件触发的this);this.setState({ count: this.state.count 1 });}}1/buttonbutton onClick{this.onIncrement}2/button/div);}
}ReactDOM.createRoot(document.getElementById(root)).render(Hello3/Hello3);A. 原因事件处理程序中this的值为undefined—抽离出来的方法用箭头函数可解决 B. 希望this指向组件实例render方法中的this即为组件实例 把state放在构造函数里面
8.事件绑定this指向
A. 抽离出的事件处理函数使用箭头函数 B. Function.prototype.bind() 【在构造函数中使用.bind(this)来绑定this上下文】 C. 在render方法中使用箭头函数来调用onIncrement但这样每次渲染都会创建一个新的函数可能会影响性能
8.1 箭头函数
A. 利用箭头函数自身不绑定this的特点 B. Render()方法中的this为组件实例可以获取到setState()
8.2 在构造函数中使用.bind(this)来绑定this上下文–Function.prototype.bind() 8.3 在render方法中使用箭头函数来调用onIncrement但这样每次渲染都会创建一个新的函数可能会影响性能
button onClick{() this.onIncrement()}2/button9.表单处理
\1. 受控组件 \2. 非受控组件DOM方式
9.1 受控组件
A. HTML中的表单元素是可输入的也就是有自己的可变状态 B. 而React中可变状态通常保存在state,并且只能通过setState()方法来修改 C.React将state与表单元素值value绑定到一起由state的值来控制表单元素的值 D. 受控组件其值受到React控制的表单元素 E. 步骤 \1. 在state中添加一个状态作为表单元素的value值控制表单元素值的来源 \2. 给表单元素绑定change事件将表单元素的值设置为state的值控制表单元素值的变化
class Hello4 extends React.Component {constructor() {super();this.state {txt: 默认值,};}inputHandle (e) {this.setState({txt: e.target.value,});};render() {return (div文本的值{this.state.txt}br /inputtypetextvalue{this.state.txt}onChange{this.inputHandle}/input/div);}
}ReactDOM.createRoot(document.getElementById(root)).render(Hello4/Hello4);示例 A.文本框、富文本框、下拉框 B.复选框
class Hello4 extends React.Component {constructor() {super();this.state {txt: 默认值,content: ,city: zj,isChecked: true,};}handleChange1 (e) {this.setState({txt: e.target.value,});};handleChange2 (e) {this.setState({content: e.target.value,});};handleChange3 (e) {this.setState({city: e.target.value,});};handleChange4 (e) {console.log(e, e4);this.setState({isChecked: e.target.checked,});};render() {return (div{/* 输入框 */}文本的值{this.state.txt}inputtypetextvalue{this.state.txt}onChange{this.handleChange1}/inputbr /{/* 文本框 */}文本框的值{this.state.content}textareavalue{this.state.content}onChange{this.handleChange2}/textareabr /{/* 下拉框 */}下拉框的值{this.state.city}select value{this.state.city} onChange{this.handleChange3}option valuezj浙江/optionoption valuejs江苏/optionoption valuesh上海/optionoption valuebj北京/option/selectbr /{/* 复选框 */}复选框的值{this.state.isChecked}inputtypecheckboxchecked{this.state.isChecked}onChange{this.handleChange4}/input/div);}
}ReactDOM.createRoot(document.getElementById(root)).render(Hello4/Hello4);9.1.1 多表单元素优化
A. 问题每个表单元素都有一个单独的事件处理程序处理太繁琐 B. 优化使用一个事件处理程序同时处理多个表单元素
9.1.2 多表单元素优化步骤
A. 给表单元素添加name属性名称与state相同 B. 根据表单元素类型获取对应值 C. 在change事件处理程序中通过[name]来修改对应的state
class Hello4 extends React.Component {constructor() {super();this.state {txt: 默认值,content: ,city: zj,isChecked: true,};}handleForm (e) {const value e.target.type checkbox ? e.target.checked : e.target.value;this.setState({[e.target.name]: value,});};render() {return (div{/* 输入框 */}文本的值{this.state.txt}inputtypetextnametxtvalue{this.state.txt}onChange{this.handleForm}/inputbr /{/* 文本框 */}文本框的值{this.state.content}textareanamecontentvalue{this.state.content}onChange{this.handleForm}/textareabr /{/* 下拉框 */}下拉框的值{this.state.city}select value{this.state.city} namecity onChange{this.handleForm}option valuezj浙江/optionoption valuejs江苏/optionoption valuesh上海/optionoption valuebj北京/option/selectbr /{/* 复选框 */}复选框的值{this.state.isChecked}inputtypecheckboxnameisCheckedchecked{this.state.isChecked}onChange{this.handleForm}/input/div);}
}ReactDOM.createRoot(document.getElementById(root)).render(Hello4/Hello4);9.2 非受控组件
A. 说明借助于ref,使用原生DOM方法来获取表单元素值 B. ref的作用获取DOM或组件 C. 使用步骤
调用React.createRef()方法创建一个ref对象将创建好的ref对象添加到文本框中通过ref对象获取到文本框的值
class Hello6 extends React.Component {constructor() {super();// 创建Refthis.textRef React.createRef();}getText () {console.log(this.textRef);console.log(this.textRef.current.value);};render() {return (divinput typetext ref{this.textRef}/inputbutton onClick{this.getText}获取文本框的值/button/div);}
}
ReactDOM.createRoot(document.getElementById(root)).render(Hello6/Hello6);10.react组件基础-案例评论列表
index.js
class Comment extends React.Component {constructor() {super();// 初始化值this.state {userName: ,userContent: ,comments: [{ id: 1, name: 周可可, content: 大家好我是周可可~~ },{ id: 2, name: 周嫑嫑, content: 每没有人能欺负周可可 },{ id: 3, name: 周深, content: 大家好我是周深~~ },{ id: 4, name: 周浅, content: 大家好我是周浅~~ },],};}// 数据展示renderList () {return this.state.comments.length 0 ? (div暂无评论快去发布吧~/div) : (divul classNamecontentDetailBox{this.state.comments.map((item) (li key{item.id}评论人{item.name}br /评论内容{item.content}/li))}/ul/div);};// 数据响应式changeForm (e) {const { name, value } e.target;this.setState({[name]: value,});};// 添加addComment () {let { userName, userContent, comments } this.state;// 非空校验if (userName.trim() || userContent.trim() ) {return alert(用户名或评论内容不能为空);}const newComments [{id: comments.length 0 ? comments.length 1 : 1,name: userName,content: userContent,},...comments,];console.log(newComments, newComments);this.setState({ comments: newComments });// 清空数据this.state.userName ;this.state.userContent ;};render() {const { userName, userContent } this.state;return (divdiv classNameappph1评论/h1divinputnameuserNameplaceholder请输入评论人classNameuserIptvalue{userName}onChange{this.changeForm}/input/divbr /div style{{ marginBottom: 10px }}textareanameuserContentplaceholder请输入评论内容rows{10}cols{50}classNamecontentTextareavalue{userContent}onChange{this.changeForm}/textarea/divbutton onClick{this.addComment}发布评论/buttondivh2 style{{ textAlign: center }}评论详情/h2{this.renderList()}/div/div/div);}
}ReactDOM.createRoot(document.getElementById(root)).render(Comment/Comment
);index.css
.appp {width: 35%;height: 700px;border: 1px solid gray;padding-left: 50px;
}.appp h1 {text-align: center;
}.userIpt {width: 40%;
}.contentDetailBox {height: 300px;overflow-y: scroll;
}