# 前言
# 特点
- 简单易学,还是比vue难
- 开发迅速
- facebook公司维护
- 社区支持火, github 106k stars, vue 201k stars
# 特性
# 声明式编程
DOM命令为命令式编程
# 组件化
组件(JSX), 提高代码复用
# 一次学习,随处编写
- web APP
- React Native 编写 手机app
- Rwact 360 做vr
# 基础知识
es6
React英文文档 (opens new window)
中文站点 (opens new window)
# 示例程序
# 组件式
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/react.development.js"></script>
<script src="js/react-dom.development.js"></script>
<script src="js/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
</body>
<script type="text/babel">
class Demo extends React.Component{
render(){
return (<div>React示例</div>)
}
}
ReactDOM.render(<Demo/>, document.getElementById("root"))
</script>
</html>
# 函数式
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/react.development.js"></script>
<script src="js/react-dom.development.js"></script>
<script src="js/babel.min.js"></script>
<style>
.red{
color: red;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script type="text/babel">
let dom = React.createElement('h2', {className:"red"},"示例")
ReactDOM.render(dom,document.getElementById('root'))
</script>
</html>
# JSX(JavaScript XML)
JSX是js的扩展,不是html
在js中写html
- 浏览器默认是不识别的,需要引用babel才能解析
- 需要有根节点
- 支持多换行,需要用()包裹
# JSX中可使用JS的表达式
- 字符串
- 数值
- boolean,一般配合三元运算符
- undefined
- []
- fn()
总结: 除了函数,其它只要有返回值即可
代码语言:javascript复制<script type="text/babel">
const name = 'React基础'
const one = 1.234
const boo = false
const can = undefined
const users = ['李雷', '韩梅梅',"魏华"]
function add(){
console.log("add")
return 3
}
class Demo extends React.Component {
render() {
return (
<div>React示例<br/>
{name}<br/>
{one}<br/>
{boo ? "OK" : "NO"}<br/>
{can == undefined ? "undefined" : "NO"}<br/>
{users}<br/>
{users.map((value) => {return value '! '})}<br/>
{users.join('-')}<br/>
{1 2 3}<br/>
{'a.b.c'.split('.')}<br/>
{add()}<br/>
</div>)
}
}
ReactDOM.render(<Demo />, document.getElementById("root"))
</script>
需要为遍历项指定一个不重复的key key 在 HTML 结构中是看不到的,是 React 内部用来进行性能优化时使用
代码语言:javascript复制<script type="text/babel">
const users = ['李雷', '韩梅梅',"魏华"]
class Demo extends React.Component {
render() {
return (
<div>React示例<br/>
{users.map((value) => {return <li key={value}>{value}</li>})}<br/>
</div>)
}
}
ReactDOM.render(<Demo />, document.getElementById("root"))
</script>
标签需要闭合,如果不是html标签则认为是一个组件
# 样式处理
# 行内样式
代码语言:javascript复制function App() {
return (
<div className="App">
<div style={{ color: 'red' }}>this is a div</div>
</div>
)
}
export default App
# className - 动态类名控制
代码语言:javascript复制import './app.css'
const showTitle = true
function App() {
return (
<div className="App">
<div className={ showTitle ? 'title' : ''}>this is a div</div>
</div>
)
}
export default App
# JSX解析
脚手架可以打断点后查看
固定数据结构的对象 为什么使用 简化代码提高开发效率 此前jQuery时代html和js是分开的,jsx逻辑在一起,不需要反复切换
# 注意事项
- class 用className代替,新版本也能生效,不过控制台会报错
- label for='xxx' 中for用htmlFor代替
- 所有html标签原生属性,都用小驼峰命名替代。如:onclick使用onClickundefined(adsbygoogle = window.adsbygoogle || []).push({});
# 组件
# 类组件与函数式组件
类组件有render函数,需要继承React.Component
代码语言:javascript复制<script type="text/babel">
function A (){
return (<div>A函数组件,<B/></div>)
}
class B extends React.Component {
render(){
return (<div>B是类组件</div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# 约定
- 组件名称首字母必须大写
- 如果没有返回值则返回null
# 函数组件的方法绑定
注意:
- {函数名},函数名首字母小写
- 默认传递的参数是点击的对象,js的事件类型,e.target.innerText为button上文字
<script type="text/babel">
function b(e){
console.log("dddddd")
console.log(e)
}
function A (){
return (<div>A函数组件,<button onClick={b} >确定</button></div>)
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
传递多个参数
代码语言:javascript复制<script type="text/babel">
function A() {
function b(e, msg) {
console.log(e)
console.log('msg', msg)
console.log(this)
}
return (<div>A函数组件,<button onClick={(e) => { b(e, 'OK') }} >确定</button></div>)
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
函数式可以直接使用内部函数,例如b,不需要使用this.b react默认使用严格模式: 未定义就不能用 函数内部第一行增加:"use strict" 未定义的变量将不能使用
# 类组件绑定
render中的this表示类实例 内部函数需要使用this.b
代码语言:javascript复制<script type="text/babel">
class A extends React.Component{
b=()=>{
console.log("@")
console.log(this)
}
render(){
return (<div>A函数组件,<button onClick={this.b} >确定</button></div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# 类组件状态(state)
安装插件Redux DevTools 数据驱动视图
state不能直接修改
需要使用setState方法,页面会自动更新
代码语言:javascript复制add = () => {
this.setState({
count: this.state.count 1,
sum: 100
})
}
# 函数组件状态
不需要this
代码语言:javascript复制<script type="text/babel">
const A = ()=>{
const [count, setCount] = React.useState(1);
const add = () => {
setCount(count 1)
}
return (<div><button onClick={add}> </button> 1 <button onClick = {add}>-</button>结果: {count}</div>)
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# 表单的受控状态
类似于双向绑定的
# 非受控表单
refs, 类组件中才有
代码语言:javascript复制<script type="text/babel">
class A extends React.Component{
login =(e)=>{
console.log(this.refs.id.value)
console.log(this.refs.pwd.value)
}
render(){
return (<div>
账号:<input ref="id"/>
密码:<input ref="pwd"/>
<button onClick={this.login}>登录</button>
</div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
函数式
代码语言:javascript复制<script type="text/babel">
const A = () => {
const id = React.useRef();
const pwd = React.useRef();
const login = (e) => {
console.log(id.current.value)
console.log(pwd.current.value)
}
return (<div>
账号:<input ref={id} /><br />
密码:<input ref={pwd} /><br />
<button onClick={login}>登录</button>
</div>)
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# 组件通信(props)
父子关系最重要
代码语言:javascript复制<script type="text/babel">
class B extends React.Component{
render(){
return (<div>我是子组件{this.props.myId}{this.props.myName} </div>)
}
}
class A extends React.Component{
state={
id: '007',
name:'德邦总管'
}
render(){
return (<div>我是父组件<B myId={this.state.id} myName = {this.state.name}/> </div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
构造方法
- 传props
- super(props)
prop里面的值是只读的不能修改
子父通讯
代码语言:javascript复制<script type="text/babel">
class B extends React.Component{
send = ()=>{
console.log('@')
this.props.to('来自子的问候')
}
render(){
return (<div>我是子组件<button onClick={this.send}>发送</button></div>)
}
}
class A extends React.Component{
state={
}
re=(data)=>{
console.log("------------")
console.log(data)
}
render(){
return (<div>我是父组件<B to={this.re}/> </div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
兄弟通讯
代码语言:javascript复制<script type="text/babel">
class C extends React.Component{
render(){
return (<div>我是C组件,{this.props.data}</div>)
}
}
class B extends React.Component{
send = ()=>{
this.props.to('来自B的问候')
}
render(){
return (<div>我是B组件<button onClick={this.send}>发送</button></div>)
}
}
class A extends React.Component{
state={
data:''
}
re=(data)=>{
this.setState({data:data})
}
render(){
return (<div>我是A组件<B to={this.re}/><C data={this.state.data}/> </div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# children
类似于Vue的插槽
代码语言:javascript复制<script type="text/babel">
class B extends React.Component{
render(){
return (<div>我是子组件{this.props.children} </div>)
}
}
class A extends React.Component{
render(){
return (<div>我是父组件<B>1234</B> </div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# props校验
用的比较少,后续用ts
代码语言:javascript复制<script type="text/babel">
class B extends React.Component {
static propTypes ={
name: PropTypes.string,
age: PropTypes.number,
}
render() {
return (<div>我是子组件<ul key={this.props.name}><li >{this.props.name} {this.props.age}</li></ul>
</div>)
}
}
class A extends React.Component {
user = {name: '李雷', age: 44 }
render() {
return (<div>我是父组件<B name={this.user.name} age={this.user.age}/> </div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# 类组件的生命周期
函数组件没有生命周期
代码语言:javascript复制<script type="text/babel">
class A extends React.Component {
componentDidMount(){
console.log("componentDidMount")
}
componentDidupdate(){
console.log("componentDidupdate")
}
render() {
return (<div>我是A组件</div>)
}
}
ReactDOM.render(<A />, document.getElementById("root"))
</script>
# 函数组件生命周期(React/useEffect)
默认render重新渲染的时候 加个参数[],就只执行一次,开发阶段脚手架项目可能会执行两次 加个参数count,监听count,变化时执行
代码语言:javascript复制<script type="text/babel">
const A = () => {
const [count, setCount] = React.useState(1);
const add = () => {
setCount(count 1)
};
React.useEffect(()=>{
console.log(Math.random())
},[count])
return (
<div>
<button onClick={add}> </button>1<button>-</button>结果:{count}
</div>
);
};
ReactDOM.render(<A />, document.getElementById("root"));
</script>
# 脚手架
可以使用jsx扩展名,语法提示更多
首字母需要大写
参考官网
# 参考
https://www.yuque.com/fechaichai/qeamqf/xbai87
https://cra.docschina.org/
(adsbygoogle = window.adsbygoogle || []).push({});