文章目录
1. React的基本使用
1.1 CDN引入所需要的文件
CDN引入需要三个文件
<!--
React:react核心库
React-dom:用于支持react操作dom
babel:jsx语法转换,jsx = js + xml
React 相关的需要在官网下载,babel 可以在 BootCDN 中找
-->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js"></script>
1.2 在html页面使用jsx语法
<body>
<!-- 创建容器 -->
<div id="app"></div>
</body>
<!-- 引入相关文件 -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js"></script>
<!-- 使用 jsx 语法 -->
<script type="text/babel">
// 创建虚拟 dom
const VDOM = <h1 id="title">hello React</h1>
// 渲染虚拟 dom 到页面上
ReactDOM.render(VDOM, document.getElementById("app"))
</script>
<!-- 使用 js 语法,这种方式不需要 babel 转换,但是比较繁琐,以后可能不经常使用 -->
<script>
// 创建虚拟 dom
const VDOM = React.creatElement("h1", {id: "title"}, "hello React")
// 渲染虚拟 dom 到页面上
ReactDOM.render(VDOM, document.getElementById("app"))
</script>
1.3 jsx语法规则
- jsx 是 js 的衍生,支持 js 语法
- 定义虚拟 DOM 时,不要写引号
- 标签中混入 JS 表达时不要用引号,要用{}
- {} 可以写表达式,不能写语句
- 样式的类名指定不要用 class,要用 className
- 内联样式要用 style={{ key: value }}的形式去写
- 只能有一个根标签
- 标签必须闭合
- 标签首字母
- 若小写字母开头,则将该标签转为 html 中同名元素,若 html 中无该标签对应的同名元素,则报错
- 若大写字母开头,react 就去渲染对应的组件,若组件没有定义,则报错
2. React组件的使用
2.1 函数式组件
- 函数必须要有返回值
- 函数名对应的组件名,首字母应该大写
- 在使用时要使用组件标签
function MyComponent() {
console.log(this) // window
return <div>我是一个函数式组件</div>
}
ReactDOM.render(<MyComponent />, document.getElementById("app"))
// 在 render 时先查看标签开头是否为大小写,如果为大写,那么就直接调用该函数
2.2 类式组件
- 需要继承 React 内置的组件
- 需要有 render 函数,并要有返回值
class MyComponent extends React.component {
render() {
console.log(this) // MyComponent {...}
return <div>我是一个类式组件</div>
}
}
ReactDOM.render(<MyComponent />, document.getElementById("app"))
// React在解析组件标签时,自动的帮忙 new 了这个类,然后实例自己调用了 render 函数,使用的也是 MyComponent 的实例(组件实例对象)
2.3 组件实例的三大属性
2.3.1 state
- state 是做 React 组件实例对象的状态管理,和 Vue 中的 data 一样
- 在修改 state 值的时候,需要使用 setState 去修改
- 下面的三种方式,都是把属性和方法挂载到组件实例对象上,在类中可以通过 this 去获取
- 函数是自己调用的,会改变 this 指向,所以需要写成箭头函数
- 每次修改 state 中的值的时候,render 函数都会调用一次
class MyComponent extends React.Component {
state = {
msg: "我是一条消息",
};
render() {
return <div onClick={this.fn}>{this.state.msg}</div>;
};
fn = () => {
let { msg } = this.state;
this.setState({
msg: msg + "!",
});
};
}
ReactDOM.render(<MyComponent />, document.getElementById("app"));
2.3.2 props
// 在使用之前需要引入 prop-types 文件,也是在 BootCDN 中可以下载
class MyComponent extends React.Component {
constructor(props) {
// 在构造函数中,如果需要通过 this 拿到 props 中的值,需要 super(porps),在其他任何地方都可以拿到
// 在 React 内部把 props 中的值添加到当前实例上了
super();
console.log("constructor", this.props); // constructor undefined
}
// 数据
state = {
msg: "我是一条消息",
};
// prop
static propTypes = {
name: PropTypes.string.isRequired, // 类型为 String,为必传
age: PropTypes.number, // 类型为 Number
};
// 默认值的配置
static defaultProps = {
age: 18,
gender: "男",
};
render = () => {
console.log("render", this.props); // render {name: '小红', age: 18, gender: '男'}
let { name, age, gender } = this.props;
return (
<div>
<ul>
<li>姓名:{name}</li>
<li>年龄:{age}</li>
<li>性别:{gender}</li>
</ul>
</div>
);
};
}
let p = {
name: "小红",
age: 18,
gender: "男",
};
// 传递的数据
// 因为 babel 做了处理,所以组件上可以 ...p 这样写
ReactDOM.render(<MyComponent {...p} />, document.getElementById("app"));
PropTypes中的类型,这点需要注意
- number
- string
- bool
- symbol
- bigint
- object
- array
- func
- any
// 函数式组件使用 props,函数式组件在 React@16.8 只能使用 props
function MyComponent(props) {
let { name, age, gender } = props;
return (
<div>
<ul>
<li>姓名:{name}</li>
<li>年龄:{age}</li>
<li>性别:{gender}</li>
</ul>
</div>
);
}
let p = {
name: "小红",
age: 18,
gender: "男",
};
// 传递的数据
ReactDOM.render(<MyComponent {...p} />, document.getElementById("app"));
2.3.3 refs
-
字符串形式的 ref
// 这种方式效率会慢一些 class Demo extends React.Component { getRefs = () => { console.log(this.refs); // {input: input, p: p, span: span} }; render() { return ( <div> <input ref="input" type="text" /> <p ref="p">我是p标签</p> <span ref="span">我是span标签</span> <br /> <br /> <button onClick={this.getRefs}>点击获取标签</button> </div> ); } } ReactDOM.render(<Demo />, document.getElementById("app"));
-
回调函数形式的 ref
// 这种方式当修改数据时,ref 的回调函数会执行两次,curNode 第一次值为 null,第二次值为当前节点 // 但是这种方式是无关紧要的,并没有什么影响 class Demo extends React.Component { state = { flag: true }; getRefs = () => { console.log(this.p); // <p>...</p> }; changeState = () => { let { flag } = this.state this.setState({ flag: !flag }) }; render() { return ( <div> <p ref={(curNode) => { this.p = curNode; console.log(curNode); }}>我是p标签</p> <button onClick={this.getRefs}>点击获取标签</button> <button onClick={this.changeState}>点击修改数据</button> </div> ); } } ReactDOM.render(<Demo />, document.getElementById("app"));
// 可以把函数提出来,这样就只会在最开始调用一次了 ref = (curNode) => { this.p = curNode } <p ref={this.refP}>我是p标签</p>
-
createRef
// 这种是 React 最推荐的 class Demo extends React.Component { refP = React.createRef(); // 此时的 refP 只能为一个标签使用 getRefs = () => { console.log(this.refP.current); // <p>...</p> }; render() { return ( <div> <p ref={this.refP}>我是p标签</p> <button onClick={this.getRefs}>点击获取标签</button> </div> ); } } ReactDOM.render(<Demo />, document.getElementById("app"));
3. React中的事件处理
- 通过 onXxx 属性指定事件处理函数 ------ 注意大小写
- React 使用的是自定义(合成)事件,而不是使用原生的 DOM 事件 ------ 为了更好的兼容性
- React 中的事件是通过事件委托方式处理的 ------ 为了高效
- 通过 event.target 得到发生事件的 DOM 元素对象,和原生的一样 ------ 不要过度的使用 ref
4. 收集表单数据
// 这种方式和 vue 中的双向绑定很相似
class Demo extends React.Component {
state = {
username: "",
password: "",
};
saveUsername = (e) => {
this.setState({
username: e.target.value,
});
};
savePassword = (e) => {
this.setState({
password: e.target.value,
});
};
render() {
return (
<div>
账号:<input onChange={this.saveUsername} type="text" name="username" placeholder="请输入账号" />
密码:<input onChange={this.savePassword} type="password" name="password" placeholder="请输入密码" />
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById("app"));
// 使用高阶函数简便写法
class Demo extends React.Component {
state = {
username: "",
password: "",
};
saveFormData = (dataType) => {
return (e) => {
this.setState({
[dataType]: e.target.value,
});
}
};
render() {
return (
<div>
账号:<input onChange={this.saveFormData("username")} type="text" name="username" placeholder="请输入账号" />
密码:<input onChange={this.saveFormData("password")} type="password" name="password" placeholder="请输入密码" />
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById("app"));