嵌入 JS 表达式
const name = 'Jack'
const dv = (
<div>你好,我叫:???</div>
)
嵌入 JS 表达式
const name = 'Jack'
const dv = (
<div>你好,我叫:{name}</div>
)
注意点:
单大括号中可以使用任意的 JavaScript 表达式
JSX 自身也是 JS 表达式
必须得有一个跟标签,跟vue组件中的一样
注意:JS 中的对象是一个例外,一般只会出现在 style 属性中
注意:不能在{}中出现语句(比如:if/for 等)
const h1 = <h1>我是JSX</h1>
const dv = (
<div>嵌入表达式:{h1}</div>
)
比如显示隐藏一个元素,类似于vue中的v-show
条件渲染:根据条件渲染特定的 JSX 结构
可以使用if/else或三元运算符或逻辑与运算符来实现,如下面代码:
const loadData = () => {
if (isLoading) {
return <div>数据加载中,请稍后...</div>
}
return (
<div>数据加载完成,此处显示加载后的数据</div>
)
}
const dv = (
<div>
{loadData()}
</div>
)
<h1 style={{ color: 'red', backgroundColor: 'skyblue' }}>
JSX的样式处理
</h1>
<h1 className="title">
JSX的样式处理
</h1>
组件是 React 的重要部分,使用 React 就是在用组件
//函数组件
function Hellow(){
return (
<h1 style={{color:'yellow'}}>我是组件Hellow</h1>
)
}
ReactDOM.render(<Hellows />, document.getElementById('root'))
// 函数组件
// function Hellow(){
// return (
// 我是组件Hellow
// )
// }
// 箭头函数
const Hellow = () => <h1 style={{ color: 'yellow' }}>我是组件Hellow</h1>
ReactDOM.render(<Hellow />, document.getElementById('root'))
类组件:使用 ES6 的 class 创建的组件
Hello.js中代码
import React from 'react'
class Hello extends React.Component {
render() {
return <div>Hello单独组件</div>
}
}
// 导出Hello组件
export default Hello
index.js中的代码
import Hello from './Hello'
// 渲染导入的Hello组件
ReactDOM.render(<Hello />, document.getElementById('root'))
React 事件绑定语法与 DOM 事件语法相似
类组件:
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>
)
}
function handleClick(e) {
e.preventDefault()
console.log('事件对象', e)
}
<button onClick={handleClick}>点我</button>
class Hello extends React.Component {
constructor() {
super()
// 初始化state
this.state = {
count: 0
}
}
render() {
return (
<div>有状态组件</div>
)
}
}
简写:
class Hello extends React.Component {
// 简化语法
state = {
count: 0
}
render() {
return (
<div>有状态组件</div>
)
}
}
class Hello extends React.Component {
// 简化语法
state = {
count: 0
}
render() {
return (
<div>有状态组件,{this.state.count}</div>
)
}
}
状态是可变的
// 正确
this.setState({
count: this.state.count + 1
})
// 错误
this.state.count += 1
class Hello extends React.Component {
onIncrement() {
this.setState({ … })
}
render() {
// 箭头函数中的this指向外部环境,此处为:render()方法
return (
<button onClick={() => this.onIncrement()}></button>
)
}
}
class Hello extends React.Component {
constructor() {
super()
this.onIncrement = this.onIncrement.bind(this)
}
// ...省略 onIncrement
render() {
return (
<button onClick={this.onIncrement}></button>
)
}
}
class Hello extends React.Component {
onIncrement = () => {
this.setState({})
}
render() {
return (
<button onClick={this.onIncrement}></button>
)
}
}
state = {
count: 0
}
this.setState({
count: this.state.count + 1
})
state = { txt: '' }
<input type="text" value={this.state.txt}
onChange={e => this.setState({ txt: e.target.value })}
/>
constructor() {
super()
this.txtRef = React.createRef()
}
<input type="text" ref={this.txtRef} />
console.log(this.txtRef.current.value)
React 组件基础
组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。在组件化过程中,我们将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能。而在这个过程中,多个组件之间不可避免的要共享某些数据。为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通,这个过程就是组件通讯
// 类props传值
// 类组件通过this.props拿到值得
class App extends React.Component {
// 推荐使用props作为constructor的参数
constructor(props) {
super(props);
// 写了构造函数就要把props传给super,不然获取不到props,但是不影响其他函数
}
render() {
// 不影响render拿到props的属性
console.log(this.props.name)
return (
<div>
<h1>props:{this.props.age}</h1>
</div>
)
}
}
ReactDOM.render(<App name="张安" age={19} />, document.getElementById('root'))
// // 父传子
class Parent extends React.Component {
state = {
name:'张三'
}
render() {
return (
<div>
<h1>父组件:{this.state.name}</h1>
<Child name={this.state.name}/>
</div>
)
}
}
// // 子组件
class Child extends React.Component {
render() {
console.log(this.props)
return (
<div>
<h1>子组件接受父组件的信息:{this.props.name}</h1>
</div>
)
}
}
ReactDOM.render(<Parent/>, document.getElementById('root'))
//父组件
class Parent extends React.Component {
state = {
msg: ''
}
// 回到函数
// 谁给我传数据,谁就调用我
getChildData = (data) => {
console.log(data)
this.setState({
msg: data
})
}
render() {
return (
<div>
<h1>父组件:{this.state.msg}</h1>
<Child getData={this.getChildData} />
</div>
)
}
}
//子组件
class Child extends React.Component {
state = {
childData: '子组件的数据'
}
hdlClick = () => {
this.props.getData(this.state.childData)
}
render() {
return (
<div>
<button onClick={this.hdlClick}>点我</button>
</div>
)
}
}
ReactDOM.render(<Parent />, document.getElementById('root'))
// 兄弟组件之间的通讯 状态提升
//父组件
//在父组件里定义共享状态,把这个状态传递给第一个子组件
class Parent extends React.Component {
state = {
contun:0
}
//在父组件中提供共享方法,通过属性传递给第二个子组件,方便第二个子组件来进行调用
// 只要第二个子组件调用了这个函数,就会执行里面代码
changeState = ()=>{
// console.log('111')
this.setState({
contun:this.state.contun + 1
})
}
render() {
return (
<div>
{/* 把状态提供给第一个子组件 */}
<Child1 contun={this.state.contun}/>
{/* 把共享方法提供给第二个子组件 */}
<Child2 changeState={this.changeState}/>
</div>
)
}
}
//子组件1
//在第一个子组件里面就能通过props获取到
const Child1 = (props)=>{
return (
<div>
<h1>{props.contun}</h1>
</div>
)
}
//子组件2
const Child2 = (props)=>{
// console.log(props)
return (
<div>
<button onClick={()=> props.changeState()}>+1</button>
</div>
)
}
ReactDOM.render(<Parent />, document.getElementById('root'))
如果出现层级比较多的情况下(例如:爷爷传递数据给孙子),我们会使用Context来进行传递
作用: 跨组件传递数据
React.createContext()
创建 Provider(提供数据) 和 Consumer(消费数据) 两个组件// Provider 提供数据 Consumer 消费数据
const { Provider, Consumer } = React.createContext()
class Parent extends React.Component {
render() {
return (
//设置value属性,表示要传递的数据
<Provider value="pink">
<div>
<h1>父组件</h1>
<Child1 />
</div>
</Provider>
)
}
}
const Child3 = () => {
return (
<Consumer >
{
data => <h1>我是child3:{data}</h1>
}
</Consumer>
)
}
React的生命周期从广义上分为三个阶段:挂载、渲染、卸载
因此可以把React的生命周期分为两类:挂载卸载过程和更新过程。
React的生命周期图:
执行时机:setState()、 forceUpdate()、 组件接收到新的props
说明:以上三者任意一种变化,组件就会重新渲染
执行顺序:
执行时机:组件从页面中消失
作用:用来做清理操作
getDerivedStateFromProps()
getDerivedStateFromProps
会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容shouldComponentUpdate()
shouldComponentUpdate()
的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染shouldComponentUpdate()
会在渲染执行之前被调用。返回值默认为 truegetSnapshotBeforeUpdate()
getSnapshotBeforeUpdate()
在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()
React 组件进阶