React基础

2022-11-18 17:13:47 浏览数 (1)

# 前言

# 特点

  1. 简单易学,还是比vue难
  2. 开发迅速
  3. facebook公司维护
  4. 社区支持火, github 106k stars, vue 201k stars

# 特性

# 声明式编程

DOM命令为命令式编程

# 组件化

组件(JSX), 提高代码复用

# 一次学习,随处编写
  1. web APP
  2. React Native 编写 手机app
  3. 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

  1. 浏览器默认是不识别的,需要引用babel才能解析
  2. 需要有根节点
  3. 支持多换行,需要用()包裹

# JSX中可使用JS的表达式

  1. 字符串
  2. 数值
  3. boolean,一般配合三元运算符
  4. undefined
  5. []
  6. 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逻辑在一起,不需要反复切换

# 注意事项

  1. class 用className代替,新版本也能生效,不过控制台会报错
  2. label for='xxx' 中for用htmlFor代替
  3. 所有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>
# 约定
  1. 组件名称首字母必须大写
  2. 如果没有返回值则返回null

# 函数组件的方法绑定

注意:

  1. {函数名},函数名首字母小写
  2. 默认传递的参数是点击的对象,js的事件类型,e.target.innerText为button上文字
代码语言:javascript复制
<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>

构造方法

  1. 传props
  2. 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({});

0 人点赞