react入门

191 阅读5分钟

关于react

react起初由Facebook工程师Jordan Walke创建,于2011年不属于Facebook的newsfeed,随后在2012年部署于Instagram,2013年5月宣布开源,近10年“陈酿”,react正在被腾讯、阿里等一线大厂广泛使用。react是用于构建用户界面的javascript库。简单的说,就是只关注视图,我们只需要做数据处理,react帮我们去操作dom呈现页面。

为什么学习react

1 原生javascript操作dom频繁,效率低

2 使用javascript直接操作dom,浏览器会进行大量的重绘重排

3 原生javascript没有组件化变成方案,代码复用率低

react特点

1 采用组件化模式、声明式编码,提高开发效率及组件复用率

2 在React Native中可以使用react语法进行移动端开发

3 使用虚拟dom+diffing算法,尽量减少与真实dom的交互

react入门

jsx

下面是关于jsx的一个最简单的demo及注意事项 image.png

jsx语法.jpg

类式组件与函数式组件

image.png 顾名思义,用函数编写的组件就是函数组件,用类编写的组件就是类组件。那什么时候需要用函数组件什么时候需要用类组件呢?下面就引出了组件三大核心属性之一,state。

state

state是用来做初始化状态的,要注意以下几点

1 state必须是一个对象

2 组件render中的this为组件实例对象

3 组件自定义的方法this是undefined 如何解决

a 强制绑定this 通过函数对象的bind()

b 箭头函数

4 状态数据不能直接修改,通过setState方法修改

eg :

    class Mycomponent extends React.Component {
           state = {
                    isHOT:true
                }
            demo = () => {
                const {isHOT} = this.state
                this.setState({
                    isHOT:!isHOT
                })
            }
            render(){
                const {isHOT} = this.state 
                return <h1 onClick={this.demo}>今天天气{this.state.isHOT?'很好':'不好'}</h1>
            }
        }
        ReactDOM.render(<Mycomponent/>,document.querySelector('#root1'))

props

props作用于给组件传值 eg:

        class Person extends React.Component {
          render(){
              const{name,age,sex} = this.props
            return(
                <ul>
                    <li>{name}</li>
                    <li>{age}</li>
                    <li>{sex}</li>
                </ul>
            )    
          }
        }
        const persons = {name:'zz',age:18,sex:'难'}
        
        ReactDOM.render(<Person {...persons}/>,document.querySelector('#root'))
        
  <script>
        // const persons = {name:'zz',age:18,}
        // console.log(...persons)  Uncaught TypeError: Found non-callable @@iterator
    </script>
       

这里要注意的是...是不能直接展开对象的,外面必须包一层{},这里是因为引用react和babel帮我们做了处理,所以可以直接用。当然我们也可以对传入的数据做限制,如限制必传,类型,默认值等。 eg:

         static propTypes = {
            name: PropTypes.string.isRequired,//设置name是string类型必填
            age: PropTypes.number,
            speak:PropTypes.func//注意设置函数不能写function 要写func 否则会报错
         }
         static defaultProps = {
            sex:'开心就好'
         }

refs

refs有三种写法

  1. 字符串形式 直接给dom绑定ref,通过this.refs拿到value。这种方法不推荐使用,官方给出的解释是string类型的ref存在一些效率问题,已经过时了并且可能会在未来的版本移除。
        class Demo extends React.Component {
          showData = ()=>{
            console.log(this.refs.input1.value)
          }
          showBlur = ()=>{
            console.log(this.refs.input2.value)
          }
          render(){
            return(
                <div>
                    <input ref="input1" type="text" placrholder="点击按钮展示数据"/>
                    <button onClick={this.showData}>点击展示</button>
                    <input ref="input2" onBlur={this.showBlur} type="text"  placrholder="失去焦点展示数据"/>
                </div>
            )    
          }
        }
  1. 回调函数类型的ref 通过回调函数,把当前节点作为参数传递后在通过this.xx.value取值。这里有一点要注意,回调函数类型的ref如果是内联函数定义的,如果这个组件以后被更新,那么会被执行两次,并且第一次传入的参数是null,第二次传入的才是dom节点。这是因为每次渲染的时候都会创建一个新的函数实例,所以react会清除旧的ref并且设置新的。通过将ref定义成class绑定函数的方式可以避免该问题。不过官方也解释说写成内联函数是无伤大雅的。

image.png 3. 通过createRef 调用该方法返回一个容器,该容器可以存储被ref所标识的节点。再通过this.xx.current.value可以获取数据。这种方法麻烦的点就是用多少个就要创建多少个容易,不过是目前官方最推荐的形式。

image.png

说完三大件也就可以回到上面的问题了,再类组件中,state、props、ref都可以用,而函数组件只能用props(暂时不考虑hooks)。在我们需要用到这些属性的时候可以用类组件,简单的组件可以用函数组件。

react事件

react中绑定事件是通过on+事件名进行绑定,要注意事件名的首字母要大写,之所以用自定义(合成)事件而非原生事件,有2点原因

  1. 为了有更高的兼容性
  2. 通过事件委托方式做出了,为了更高的效率

生命周期

/**
         * 生命周期 
         * 旧版本
         * 1 初始化阶段:由ReactDOM.render()触发 =>初次渲染
         *        1. constructor()
         *        2. componentWillMount() 废弃
         *        3. render()
         *      * 4. componentDidMount() 一般再这个钩子做初始化 开启定时器、发送网络请求、订阅消息
         * 
         * 2 更新阶段:由组件内部this.setState()或父组件render触发
         *        1. shouldComponentUpdate()
         *        2. componentWillUpdate() 废弃
         *        3. render()
         *        4. componentDidUpdate()
         * 
         * 3 卸载过程 
         *      * 1.componentWillUnmount() 收尾 关闭定时器、取消订阅消息等
         * 
         * 
         * 新版本 
         * 1 初始化阶段:由ReactDOM.render()触发 =>初次渲染
         *        1. constructor()
         *        2. getDerivedStateFromProps
         *        3. render()
         *      * 4. componentDidMount()
         * 2 更新阶段:由组件内部this.setState()或父组件render触发
         *        1. getDerivedStateFromProps
         *        2. shouldComponentUpdate()
         *        3. render()
         *        4. getSnapshotBeforeUpdate
         *        4. componentDidUpdate()
         * 3 卸载过程  由ReactDOM.UnmountComponentAtNode()触发
         *      * 1.componentWillUnmount()
         * 
        */

hooks

hook是react16.8版本新增加的新特性,可以再函数式组件使用state以及其他react特性

State Hook:React.useState()

让函数也有state状态并进行读写操作。 参数说明:第一次初始化指定的值会在内部作缓存。返回值是两个元素的数组,第一个是内部当前状态值,第二个为更新状态值的函数

         const Demo = () => {
          const [count,setCount] = React.useState(0)
          const add = () =>{
            //setCount(count+1)
            setCount(count => count+1)
          }
          return (
            <div>
              <h2>和:{count}</h2>
              <button onClick={add}>点我加1</button>
            </div>
          )
        }
        
        ReactDOM.render(<Demo />,document.querySelector('#root'))

Effect Hook

用于模拟类组件中的生命周期

 const Demo = () => {
          const [count,setCount] = React.useState(0)

          React.useEffect(()=>{
           let timer= setInterval(()=>{
              setCount(count=>count+1)
            },1000)
           return clearInterval(timer) //做收尾工作 相当于componentWillUnmount
          },[])
          /**
           * 不写数组要监测所有属性 再初始化和更新时触发,相当于(componentDidMount和componentDidUpdate) 
           * 空数组是所有都不监测 只在第一次render后执行 相当于(componentDidMount) */
          const add = () =>{
            //setCount(count+1)
            setCount((count)=>{
              return count
            })
            //console.log(count)
          }
          return (
            <div>
              <h2>和:{count}</h2>
              <button onClick={add}>点我加1</button>
            </div>
          )
        }

Ref Hook

可以再函数组件中存储或者查找组件内标签或者其他数据,和React.creatRef()用法功能类似

 const Demo = () => {
          const myRef = React.useRef()
          const clickme = ()=>{
            console.log(myRef.current.value)
          }
          return (
            <div>
              <input type="text" ref={myRef}/>
              <button onClick={clickme}>点我</button>
            </div>
          )
        }
        
        ReactDOM.render(<Demo />,document.querySelector('#root'))