JSX语法介绍
JSX语法:JavaScript + XML语法(HTML)
解读jsx语法:遇到<>安装HTML语法解析,遇到{}按照JavaScript
const element = <h1>Hello, world!</h1>;
元素渲染
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000);
组件
组件的后缀可以是js,也可以是jsx
一个React项目,是由成千上万个组件组成
import React from "react"
export default class Home extends React.Component{
render(){
return(
<div>
Home
</div>
)
}
}
porps属性
组件的复用性很重要
myNav.jsx
import React from "react"
// props不可以被修改
export default class MyNav extends React.Component{
render(){
console.log(this.props.nav);
return(
<div>
{/* jsx语法 */}
<h3>{ this.props.title }</h3>
<ul>
{
this.props.nav.map((element,index) => {
return <li key={index}>{ element }</li>
})
}
</ul>
</div>
)
}
}
App.jsx
import React from "react"
import Home from "./Home"
import MyNav from "./myNav"
// 用类的形式创建组件,Hook形式
class App extends React.Component{
// 渲染函数
render(){
const nav1 = ["首页","视频","学习"];
const nav2 = ["WEB","Java","Node"];
return(
<div>
<h1>Hello React Component</h1>
<h3>学习React,最重要的是,心态要好!</h3>
<Home />
<MyNav nav={ nav1 } title="路径导航"/>
<MyNav nav={ nav2} title="学习导航"/>
</div>
)
}
}
export default App
事件处理
- this问题
- 向事件处理程序传递参数
state状态
import React from "react"
export default class StateComponent extends React.Component{
/**
* 组件中的状态:state
* 以前我们操作页面的元素的变化,都是修改DOM,操作DOM
* 但是有了React优秀的框架,我们不在推荐操作DOM,页面元素的改变使用state进行处理
*/
constructor(props){
super(props);
// 定义
this.state = {
count: 10,
flag: true
}
}
increment(){
// setState
this.setState({
count: this.state.count += 1
})
}
decrement(){
this.setState({
count: this.state.count -= 1
})
}
clickHandler = () => {
console.log(this);
}
render(){
let showView = this.state.flag ? "我是孙悟空" : "我是假的孙悟空";
return(
<div>
<h3>组件的State</h3>
<p>{ this.state.count }</p>
<button onClick={ this.increment.bind(this) }>增加</button>
<button onClick={ this.decrement.bind(this) }>减少</button>
<button onClick={ this.clickHandler }>关于this</button>
<p>{ showView }</p>
</div>
)
}
}
React生命周期函数
随着我们对React理解和使用越来越多,生命周期的参考价值越来越高
函数列表:
componentWillMount:在组件渲染之前执行
componentDidMount: 在组件渲染之后执行
shouldComponentUpdate: 返回true和false,true代表允许改变,false代表不允许改变
componentWillUpdate: 数据在改变之前执行(state,props)
componentDidUpdate: 数据修改完成(state,props)
componentWillReveiceProps: props发生改变执行
componentWillUnmount: 组件卸载前执行
子传父
父传子
app.jsx
import React from 'react';
import ComponentLife from './ComponentLife';
// 用类的形式创建组件,Hook形式
class App extends React.Component {
constructor() {
super();
this.state = {
title: '文本1',
};
}
clickChange = (data) => {
this.setState({
title: data,
});
};
// 渲染函数
render() {
return (
<div>
<ComponentLife
title={this.state.title}
clickChanges={this.clickChange}
/>
</div>
);
}
}
export default App;
ComponentLife.jsx
import React from 'react';
export default class ComponenLife extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 10,
};
}
componentWillMount() {
console.log('componentWillMount');
}
componentDidMount() {
console.log('componentDidMount');
}
shouldComponentUpdate() {
console.log('shouldComponentUpdate');
return true;
}
componentWillUpdate() {
console.log('componentWillUpdate');
}
componentDidUpdate() {
console.log('componentDidUpdate');
}
componentWillReceiveProps() {
console.log('componentWillReceiveProps');
}
componentWillUnmount() {
console.log('componentWillUnmount');
}
changeHandler = () => {
this.setState({
count: (this.state.count += 1),
});
};
clickChange = () => {
this.props.clickChanges('我是儿子的数据');
};
render() {
const { count } = this.state;
return (
<div>
生命周期函数:{count} - {this.props.title}
<button onClick={this.changeHandler}>修改</button>
<button onClick={this.clickChange}>子传父修改title</button>
</div>
);
}
}
setState更新是同步还是异步
- setState会引起视图的重绘
- 在可控的情况下是异步,在非可控的情况下是同步
es6的新特性
setStateDemo.jsx
import React from 'react';
export default class SetStateDemo extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
// increment =() =>{
// // 不能实时的获取this.state.count,每次获取的都是上一次的值
// // this.setState({
// // count: this.state.count + 1
// // })
// // console.log(this.state.count);
// 方法一:
// this.setState({
// count: this.state.count + 1
// },() => {
// console.log(this.state.count);
// })
// }
// 方法二:
// 异步更改成同步
async increment() {
await this.setStateAsync({ count: this.state.count + 1 });
console.log(this.state.count);
}
// 知识点:promise async await
setStateAsync(state) {
return new Promise((resolve) => {
this.setState(state, resolve);
});
}
render() {
return (
<div>
setState同步还是异步问题
<p>{this.state.count}</p>
<button onClick={this.increment.bind(this)}>修改</button>
</div>
);
}
}
条件渲染
ifDemo.jsx
import React from "react"
export default class IfDemo extends React.Component{
/**
* 常用的应用常见:
* 1.对视图条件进行切换
* 2.做缺省值
*/
constructor(){
super();
this.state = {
isLogin: false,
names: ["iwen","ime"]
}
}
clickHandler = () => {
this.setState({
isLogin: true
})
}
render(){
const { names } = this.state;
let showView = this.state.isLogin ?
<div>iwen</div> :
<div>请登录</div>
return(
<div>
条件渲染:{ showView }
<button onClick = { this.clickHandler }>登录</button>
{
names.length > 0 ?
<div>
{
names.map((element,index) => {
return <p key={ index }>{ element }</p>
})
}
</div>
:
<div>请等待数据正在请求......</div>
}
</div>
)
}
}
列表 & Key
主要问题是key
key的原理解析:https://blog.csdn.net/handsomexiaominge/article/details/86560003
KeyDemo.jsx
import React from "react"
export default class KeyDemo extends React.Component{
constructor(){
super();
this.state = {
userinfo: [{
name: "iwen",
age: 20,
sex: "男",
jobs: ['1','22','333']
},{
name: "ime",
age: 20,
sex: "男",
jobs: ['1','22','333']
},{
name: "frank",
age: 20,
sex: "男",
jobs: ['1','22','333']
}]
}
}
clickHandler = () => {
this.setState({
userinfo: this.state.userinfo.concat({
name: "liang",
age: 30,
sex: "男",
jobs: ['1','22','333']
})
})
}
render(){
return(
<div>
<ul>
{
this.state.userinfo.map((element,index) =>{
return(
<li key={ index }>
<span>{ element.name }</span>
<span>{ element.age }</span>
<span>{ element.sex }</span>
<div>
{
element.jobs.map((childElement,childIndex) => {
return(
<span key={ childIndex }>{ childElement }</span>
)
})
}
</div>
</li>
)
})
}
</ul>
<button onClick={ this.clickHandler }>添加数据</button>
</div>
)
}
}
表单
- 受控组件
- 非受控组件
FormDemo.jsx
import React from 'react';
// 表单受控组件
export default class FormDemo extends React.Component {
constructor() {
super();
this.state = {
value: '',
};
}
handleSubmit = (e) => {
e.preventDefault();
console.log(this.state.value);
};
onChangeHandler = (e) => {
this.setState({
value: e.target.value,
});
};
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input
type="text"
value={this.state.value}
onChange={this.onChangeHandler}
/>
<input type="submit" value="提交" />
</form>
</div>
);
}
}
Refs and the DOM
1.管理局焦点,文本选择或媒体播放
2.触发强制动画
3.继承第三方 DOM 库
RefAndDOM.jsx
import React from "react"
// Refs和DOM
export default class RefsAndDOM extends React.Component{
constructor(){
super();
this.HelloDiv = React.createRef();
}
componentDidMount(){
this.HelloDiv.current.style.color = "red";
}
render(){
return(
<div>
Refs和DOM
<div ref={ this.HelloDiv }>
Hello
</div>
</div>
)
}
}
RefsForm.jsx
import React from 'react';
// 非受控组件
export default class RefsForm extends React.Component {
constructor() {
super();
this.username = React.createRef();
this.password = React.createRef();
}
clickHandler = (e) => {
console.log(this.username.current.value);
console.log(this.password.current.value);
};
render() {
return (
<div>
<input type="text" ref={this.username} />
<input type="text" ref={this.password} />
<button onClick={this.clickHandler}>提交</button>
</div>
);
}
}
状态提升
组件之间的数据交互
parent.jsx
import React from "react"
import Child1 from "./child1"
import Child2 from "./child2"
export default class Parent extends React.Component{
constructor(){
super();
this.state = {
money: 7
}
}
changeHandler(e){
this.setState({
money: e.target.value
})
}
render(){
return(
<div>
<input type="text" value={ this.state.money } onChange={ this.changeHandler.bind(this)} />
<p>Parent</p>
人民币: <Child1 money={ this.state.money } />
美元: <Child2 money={ this.state.money } />
</div>
)
}
}
child1.jsx
import React from "react"
export default class Child1 extends React.Component{
constructor(){
super();
this.state = {
input: 0
}
}
componentDidMount(){
this.setState({
input: this.props.money
})
}
changeHandler(e){
this.setState({
input1: e.target.value
})
}
render(){
return(
<div>
<p>{ this.props.money }</p>
<input type="text" value={ this.state.input } onChange={ this.changeHandler.bind(this) } />
</div>
)
}
}
child2.jsx
import React from 'react';
export default class Child2 extends React.Component {
constructor() {
super();
this.state = {
input: 0,
};
}
componentDidMount() {
console.log(this.props.money);
this.setState({
input: this.props.money / 7,
});
}
changeHandler(e) {
this.setState({
input: e.target.value,
});
}
render() {
return (
<div>
<p>{this.props.money / 7}</p>
<input
type="text"
value={this.state.input}
onChange={this.changeHandler.bind(this)}
/>
</div>
);
}
}
组合 vs 继承
this.props.children
使用 PropTypes 进行类型检查
增强组件的健壮性
app.jsx
import React from 'react';
import PropsTypeDemo from './PropsTypeDemo';
// 用类的形式创建组件,Hook形式
class App extends React.Component {
constructor() {
super();
}
// 渲染函数
render() {
return (
<div>
<PropsTypeDemo />
</div>
);
}
}
export default App;
PropsTypeDemo.jsx
import React from 'react';
import PropTypes from 'prop-types';
export default class PropsTypeDemo extends React.Component {
render() {
return <div>Hello:{this.props.title}</div>;
}
}
// PropsTypeDemo.PropTypes = {
// title: PropTypes.number.isRequired
// }
PropsTypeDemo.propTypes = {
title: PropTypes.string,
};
PropsTypeDemo.defaultProps = {
title: '默认值',
};