前言
最近做一个项目需要用到react,就开始学习一下react吧
1.起步
1.React安装
npm i react react-dom
<div id="root"></div>
<!-- 1 引入js文件 -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<script>
// 2 创建react元素
// 参数一:元素名称
// 参数二:元素属性
// 参数三:元素的子节点
const title = React.createElement('h1', null, 'Hello React')
// 3 渲染react元素
// 参数一:要渲染的react元素
// 参数二:挂载点
ReactDOM.render(title, document.getElementById('root'))
</script>
2.安装脚手架
npx create-react-app my-app
导入react
import React from 'react'
import ReactDOM from 'react-dom'
3.JSX 的基本使用
JSX自动补全html标签
const title = <h1>hello jsx</h1>
?注意点
JS表达式
/*
JSX中使用JavaScript表达式
*/
const name = 'Jack'
const age = 19
const title = (
<h1>
Hello JSX, {name}, 年龄:{age}
</h1>
)
?JSX中使用JavaScript表达式的注意点:
import React from 'react'
import ReactDOM from 'react-dom'
/*
JSX中使用JavaScript表达式的注意点:
*/
// 函数调用表达式
const sayHi = () => 'Hi~'
const dv = <div>我是一个div</div>
const title = (
<h1>
Hello JSX
<p>{1}</p>
<p>{'a'}</p>
<p>{1 + 7}</p>
<p>{3 > 5 ? '大于' : '小于等于'}</p>
<p>{sayHi()}</p>
{dv}
{/* 错误演示 */}
{/* <p>{ {a: '6'} }</p> */}
{/* { if (true) {} } */}
{/* { for (var i = 0; i < 10; i++) {} } */}
</h1>
)
// 渲染react元素
ReactDOM.render(title, document.getElementById('root'))
结果
条件渲染
const isLoading = true
// 逻辑与运算符:
const loadData = () => {
return isLoading && (<div>loading...</div>)
}
const title = (
<h1>
条件渲染:
{loadData()}
</h1>
)
?
const isLoading = true
// if-else
const loadData = () => {
if (isLoading) {
return <div>loading...</div>
}
return <div>数据加载完成,此处显示加载后的数据</div>
}
const isLoading = false
// 三元表达式:
const loadData = () => {
return isLoading ? (<div>loading...</div>) : (<div>数据加载完成,此处显示加载后的数据</div>)
}
?
列表渲染
/*
列表渲染:
*/
// 歌曲列表:
const songs = [
{id: 1, name: '痴心绝对'},
{id: 2, name: '像我这样的人'},
{id: 3, name: '南山南'},
]
const list = (
<ul>
{songs.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)
// 渲染react元素
ReactDOM.render(list, document.getElementById('root'))
css
4.React组件
创建组件的两种方法
?函数组件
?
const Hello=()=> <div>函数组件</div>
// 渲染react元素
ReactDOM.render(<Hello/>, document.getElementById('root'))
类组件
class Hello extends React.Component {
render() {
return (
<div>第一个类组件</div>
)
}
}
// 渲染react元素
ReactDOM.render(<Hello/>, document.getElementById('root'))
5.React 事件处理
事件绑定
类组件事件绑定
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>
)
}
事件对象?
class App extends React.Component {
handleClick(e) {
// 阻止浏览器的默认行为
e.preventDefault()
console.log('a标签的单击事件触发了')
}
render() {
return (
<a href="http://itcast.cn/" onClick={this.handleClick}>zjhhhhh</a>
)
}
}
6.有状态组件和无状态组件
?state的基本使用
?
?
class App extends React.Component {
/* constructor() {
super()
// 初始化state
this.state = {
count: 0
}
} */
// (es6)简化语法初始化state(推荐)
state = {
count: 10
}
render() {
return (
<div>
<h1>计数器:{ this.state.count }</h1>
</div>
)
}
}
setState的基本使用
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>
)
}
}
7.this指向问题
JSX中掺杂过多JS逻辑代码,会显得非常混乱,所以我们将逻辑抽离到单独的方法中,保证JSX 结构清晰
如下列代码
class App extends React.Component {
state = {
count: 0
}
// 事件处理程序
onIncrement() {
console.log('事件处理程序中的this:', this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{ this.state.count }</h1>
<button onClick={this.onIncrement}>+1</button>
{/* <button onClick={() => {
this.setState({
count: this.state.count + 1
})
}}>+1</button> */}
</div>
)
}
}
但是运行会报错
原因是事件处理程序中this的值为undefined,我们希望this指向组件实例(render方法的this即为组件实例)
有三种解决方法
1.箭头函数
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
this.onIncrement = this.onIncrement.bind(this)
}
// 事件处理程序
onIncrement() {
console.log('事件处理程序中的this:', this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{ this.state.count }</h1>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
?2.Function.prototype.bind()
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
this.onIncrement = this.onIncrement.bind(this)
}
// 事件处理程序
onIncrement() {
console.log('事件处理程序中的this:', this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{ this.state.count }</h1>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
?3.class的实例方法
?
class App extends React.Component {
state = {
count: 0
}
// 事件处理程序
onIncrement = () => {
console.log('事件处理程序中的this:', this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{ this.state.count }</h1>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
8.表单处理
?受控组件
?
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>
)
}
}
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}></textarea>
<br/>
{/* 下拉框 */}
<select value={this.state.city} onChange={this.handleCity}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="gz">广州</option>
</select>
<br/>
{/* 复选框 */}
<input type="checkbox" checked={this.state.isChecked} onChange={this.handleChecked} />
</div>
)
}
}
?多表单元素的优化
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}></textarea>
<br/>
{/* 下拉框 */}
<select name="city" value={this.state.city} onChange={this.handleForm}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="gz">广州</option>
</select>
<br/>
{/* 复选框 */}
<input type="checkbox" name="isChecked" checked={this.state.isChecked} onChange={this.handleForm} />
</div>
)
}
}
?非受控组件
?
class App extends React.Component {
constructor() {
super()
this.txtRef=React.createRef()
}
gettxt=()=> {
console.log('文本框的值为:',this.txtRef.current.value);
}
render() {
return (
<div>
<input type="text" ref={this.txtRef}/>
<button onClick={this.gettxt}>获取文本框的值</button>
</div>
)
}
}
?
?
|