使用函数创建组件
函数组件:使用JS的函数(或箭头函数)创建的组件
约定1:函数名称必须以大写字母开头,React据此区分组件和普通的React元素
约定2:函数组件必须有返回值,表示该组件的结构
如果返回值为null,表示不渲染任何内容
渲染函数组件:用函数名作为组件标签名
组件标签可以是单标签也可以是双标签
示例:
const Hello = () => (<div>这是我的第一个函数组件!!!</div>)
使用类创建组件
类组件:使用ES6 的class创建的组件
约定1:类名称也必须以大写字母开头
约定2:类组件应该继承React.Component父类,从而可以使用父类中提供的方法或属性
约定3:类组件必须提供render()方法
约定4:render()方法必须有返回值,表示该组件的结构
示例:
class Hello extends React.Component { render() { return ( <div>这是我的第一个类组件!!!</div> ) } } // 渲染组件 ReactDOM.render(<Hello />, document.getElementById('root'))
抽离为独立JS文件
1、创建Hello.js
2、在Hello.js中导入React
3、创建组件(函数或类)
4、在Hello.js中导出该组件
5、在index.js中导入Hello组件
6、渲染组件
示例:
// Hello.js import React from "react"; class Hello extends React.Component{ render() { return ( <div>第一个抽离的组件</div> ) } } export default Hello // index.js import Hello from "./Hello"; ReactDOM.render(<Hello />, document.getElementById('root'))
事件绑定
React事件绑定语法与DOM事件语法相似
语法:on+事件名称={事件处理程序},比如:onClick={()=>{}}
注意:React事件采用驼峰命名法,比如onMouseEnter、onFocus
示例:
// 方式一,使用class class App extends React.Component { handleClick(){ console.log('点击成功') } render() { return ( <button onClick={this.handleClick}>点我</button> ) } } // 方式一,使用函数 function App() { function handleClick(){ console.log('点击成功') } return ( <button onClick={handleClick}>点我</button> ) } ReactDOM.render(<App/>, document.getElementById('root'))
事件对象
可以通过事件处理程序的参数获取到事件对象
React中的事件对象叫做:合成事件(对象)
合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
示例:
class App extends React.Component{ handleClick(e){ // 阻止浏览器行为 e.preventDefault() console.log('阻止浏览器行为') } render() { return ( <a href="https://www.baidu.com/" onClick={this.handleClick}>百度</a> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
state的基本使用
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用
state的值是对象,表示一个组件中可以有多个数据
通过this.state 来获取状态
示例:
class App extends React.Component { // constructor() { // super(); // this.state = { // count: 0 // } // } // 精简版 state = { count: 0 } render() { return ( <div>有状态组件, {this.state.count}</div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
setState()修改状态
状态是可变的
语法:this.setState({要修改的数据})
注意:不要直接修改state中的值,这是错误的!!!
setState()作用:1.修改state 2.更新UI
思想:数据驱动视图
示例:
class App extends React.Component { state = { count: 0, test: 'a' } render() { return ( <div> <h1>计数器: {this.state.count}</h1> <button onClick={ ()=> { this.setState({ count: this.state.count + 1 }) // 错误示例 // this.state.count += 1 } }>+1 </button> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
从JSX中抽离事件处理程序
1.箭头函数
利用箭头函数自身不绑定this的特点
render()方法中的this为组件实例,可以获取到setState()
示例:
class App extends React.Component { state = { count: 0 } onIncrement(){ console.log(this) this.setState({ count: this.state.count + 1 }) } render() { return ( <div> <h1>计数器: {this.state.count}</h1> <button onClick={() => this.onIncrement()}> +1 </button> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
2.Function.prototype.bind()
利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定到一起
示例:
class App extends React.Component { constructor() { super(); this.state = { count: 0 } this.onIncrement = this.onIncrement.bind(this) } onIncrement(){ console.log(this) this.setState({ count: this.state.count + 1 }) } render() { return ( <div> <h1>计数器: {this.state.count}</h1> <button onClick={this.onIncrement}> +1 </button> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
3.class的实例方法
利用箭头函数形式的class实例方法
注意:该语法是实验性语法,但是,由于babel的存在可以直接使用
示例:
class App extends React.Component { state = { count: 0 } onIncrement = () => { console.log(this) this.setState({ count: this.state.count + 1 }) } render() { return ( <div> <h1>计数器: {this.state.count}</h1> <button onClick={this.onIncrement}> +1 </button> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
1.受控组件
HTML中的表单元素是可输入的,也就是自己的可变状态
而,React中可变状态通常保存在state中,并且只能通过setState()方法来修改
React将state与表单元素值value绑定在一起,由state的值来控制表单元素的值
受控组件:其值受到React控制的表单元素
示例:
<input type="text" value={this.state.txt} />
步骤:
1.在state中添加一个状态,作为表单元素的value值(控制表单元素的来源)
2.给表单元素绑定change事件,将表单元素的值设置为state的值(控制表单元素值的变化)
示例:
class App extends React.Component{ state = { txt: '' } handleChange = (e) => { this.setState({ txt: e.target.value }) } render() { return ( <div> <input type="text" value={this.state.txt} onChange={this.handleChange} /> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
示例总结:
文本框、富文本框、下拉框 操作value属性
复选框 操作checked属性
示例:
class App extends React.Component{ state = { txt: '', content: '', city: 'bj', isChecked: false } // 处理文本 handleChange = e => { this.setState({ txt: e.target.value }) } // 处理富文本 handleContent = e => { this.setState({ content: e.target.value }) } // 处理下拉框 handleCity = e => { this.setState({ city: e.target.value }) } // 处理复选框 handleChecked = e => { this.setState({ isChecked: e.target.checked }) } render() { return ( <div> {/*文本框 */} <input type="text" value={this.state.txt} onChange={this.handleChange} /> <br/> {/*富文本框 */} <textarea value={this.state.content} onChange={this.handleContent}/> <br/> {/*下拉框 */} <select value={this.state.city} onChange={this.handleCity}> <option value="sh">上海</option> <option value="bj">北京</option> <option value="nj">南京</option> </select> <br/> {/*复选框 */} <input type="checkbox" checked={this.state.isChecked} onChange={this.handleChecked}/> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
多表单元素优化:
问题:每个表单元素都有一个单独的事件处理程序处理太繁琐
优化:使用一个事件处理程序同时处理多个表单元素
优化步骤:
1.给表单元素添加name属性,名称与state相同
2.根据表单元素类型获取对应值
3.在change事件处理程序中通过[name]来 修改对应的state
示例:
class App extends React.Component{ state = { txt: '', content: '', city: 'bj', isChecked: false } handleForm = e => { // 获取当然dom对象 const target = e.target // 根据类型获取值 const value = target.type === 'checkbox' ? target.checked : target.value // 获取name const name = target.name this.setState({ [name]: value }) } render() { return ( <div> {/*文本框 */} <input type="text" name="txt" value={this.state.txt} onChange={this.handleForm} /> <br/> {/*富文本框 */} <textarea name="content" value={this.state.content} onChange={this.handleForm}/> <br/> {/*下拉框 */} <select name="city" value={this.state.city} onChange={this.handleForm}> <option value="sh">上海</option> <option value="bj">北京</option> <option value="nj">南京</option> </select> <br/> {/*复选框 */} <input type="checkbox" name="isChecked" checked={this.state.isChecked} onChange={this.handleForm}/> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))
2.非受控组件
说明:借助于ref,使用原生DOM方式来获取表单元素值
ref的作用:获取DOM或组件
步骤:
1.调用React.createRef()方法创建一个ref对象
2.将创建好的ref对象添加到文本框中
3.通过ref对象获取到文本框的值
示例:
class App extends React.Component { constructor() { super(); // 创建ref this.txtRef = React.createRef() } // 获取文本框的值 getTxt = () => { console.log('打印') console.log(this.txtRef.current.value) } render() { return ( <div> {/*文本框 */} <input type="text" ref={this.txtRef} /> <button onClick={this.getTxt}>获取文本框的值</button> </div> ) } } ReactDOM.render(<App/>, document.getElementById('root'))