React基础知识点

React

import React from 'react'

一、jsx

1.jsx是一个变量也是一个对象

2.jsx可以以使用静态和动态属性

3.jsx本身就是表达式,内部也可以使用表达式(用大括号包裹)

4.jsx可以任意嵌套(用大括号包裹)

5.jsx中的注释也是变量(用大括号包裹)

6.jsx中可以绑定变量

const ele = <h2>我是jsx变量<h2>

(具体效果参考以下类组件项)

二、react组件定义方式

类组件

export default class TestJsx extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            msg:'hello msg jsx',
            color:'red',
            style:{color:pink,font-size:50px}
        }
    }
    // 外部jsx变量嵌套
    createChild() {
        return (
        	<div>
            	<span>我是嵌套的jsx变量</span>
                {ele}
            </div>
        )
    }
    // jsx事件方法
    changeColor() {
        this.setState({
            color:'blue'
        })
    }
	render() {
        return (
        	<div>
            	<h1>JSX</h1>
                {ele}
                <h2 title='jsx'>jsx静态属性<h2>
                <h2 className={this,state.color}>JSX动态属性</h2>
                <h2>{this.state.msg}</h2>
                <h2>{this.state.createChild()}</h2>
                {/* 这是注释 */}
                <button onClick={this.changeColor.bind(this)}>jsx的事件</button>
                <h2 style={{color:'orange',font-size:'40px'}}>jsx内置样式</h2>
                <h2 style={this.state.style}>jsx内置样式</h2>
            </div>
        )
    }
}

函数组件(无状态组件)

1.它没有状态state

2.它没有生命周期

3.它没有this

4.它唯一好处是性能好,这是react性能优化方式之一

props:

1.用于父组件传子组件值

2.只读,不能操作(不能修改,不能用于赋值)

3.props和state没有关系,不能相互赋值

export default function Child1(props) {
	return(
        <div className='child'>
            <h2>这是一个函数组件,{props.aaa}</h2>
            {props.children}
        </div>
	)
}
<Child1 aaa='我是父组件传的值' >
    <span>我是父组件传递的标签元素</span>
</Child1>

ES5组件

React.createClass

var InputControlES5 = React.createClass({
    propTypes: {//定义传入props中的属性各种类型
        initialValue: React.PropTypes.string
    },
    defaultProps: { //组件默认的props对象
        initialValue: ''
    },
    // 设置 initial state
    getInitialState: function() {//组件相关的状态对象
        return {
            text: this.props.initialValue || 'placeholder'
        };
    },
    handleChange: function(event) {
        this.setState({ //this represents react component instance
            text: event.target.value
        });
    },
    render: function() {
        return (
            <div>
                Type something:
                <input onChange={this.handleChange} value={this.state.text} />
            </div>
        );
    }
});
InputControlES6.propTypes = {
    initialValue: React.PropTypes.string
};
InputControlES6.defaultProps = {
    initialValue: ''
};

React.Component

class InputControlES6 extends React.Component {
    constructor(props) {
        super(props);

        // 设置 initial state
        this.state = {
            text: props.initialValue || 'placeholder'
        };

        // ES6 类中函数必须手动绑定
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        this.setState({
            text: event.target.value
        });
    }

    render() {
        return (
            <div>
                Type something:
                <input onChange={this.handleChange}
               value={this.state.text} />
            </div>
        );
    }
}
InputControlES6.propTypes = {
    initialValue: React.PropTypes.string
};
InputControlES6.defaultProps = {
    initialValue: ''
};

Hooks组件

高阶组件

三、事件处理

事件规范‘on+事件’

// 事件如何传参?

// bind()方式绑定,this.clickHandle.bind(this, ‘arg1’, ‘arg2’)

// 箭头函数方式绑定,(e)=>this.clickHandle(‘arg1’, e, ‘arg2’)

export default class TestEvent extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            num: 1
        }
        this.clickHandle1 = this.clickHandle.bind(this)
    }

    clickHandle() {
        this.state.num++
        this.setState({
            num: this.state.num
        })
    }
    // stop(e) {
    //     // 默认事件阻止
    //     e.preventDefault()
    //     // 冒泡事件阻止
    //     e.stopPropagation()//w3c标准
    //	   e.cancelBubble = true//ie
    // }
    render() {
        return (
            <div>
                <h2>{this.state.num}</h2>
                {/* 方式一 */}
                <div onClick={this.clickHandle.bind(this)}>写法一</div>
                <div onClick={this.clickHandle1}>写法二</div>
                {/* 方式二 */}
                <div onClick={() => this.clickHandle(this)}>写法三</div>
            </div>
        )
    }
}

四、条件渲染

import React from 'react'

export default class TestCondition extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            bol1: true,
            bol2: false,
            bol3: 1,
            dis: 'block'
        }
    }
    creatViews() {
        let { bol3 } = this.state
        let ele
        switch (bol3) {
            case 1:
                ele = <div>111111</div>
                break;
            case 2:
                ele = <div>222222</div>
                break;
            default:
                ele = <div>555555</div>
                break;
        }
        return ele
    }
    render() {
        let { bol1, bol2, dis } = this.state
        return (
            <div>
                <h1>条件渲染</h1>
                {bol1 && <div>111111</div>}
                <hr />
                {bol2 && <div>222222</div>}
                {!bol2 && <div>333333</div>}
                <hr />
                {bol2 ? <div>222222</div> : <div>333333</div>}
                <hr />
                {this.creatViews()}
                <hr/>
                <div style={{display:dis}}>666666</div>
            </div>
        )
    }
}

五、列表渲染

import React from 'react'

export default class TestCondition extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            list: [
                { id: 1, name: 'list1' },
                { id: 2, name: 'list2' },
                { id: 3, name: 'list3' },
                { id: 4, name: 'list4' },
                { id: 5, name: 'list5' },
            ]
        }
    }
    // 方式二
    createList1() {
        let { list } =this.state
        return list.map(ele=>(
            <div key={ele.id}>{ele.name}</div>
        ))
    }
    // 方式三
    createList2() {
        let { list } =this.state
        let arr = []
        list.map(ele=>{
            arr.push(
                <div key={ele.id}>{ele.name}</div>
            )
        })
        return arr
    }
    render() {
        let { list } = this.state
        return (
            <div>
                <h1>列表渲染</h1>
                {list.map(ele => (
                    <div key={ele.id}>{ele.name}</div>
                ))}
                <hr/>
                {this.createList1()}
                <hr/>
                {this.createList2()}
            </div>
        )
    }
}

六、父子组件传值

1、父组件传值子组件:

在父组件的render() 的jsx中,自定义属性名,并赋需要传的值

2、子组件接收父组件:

使用this.props.自定义属性名获取传递的值

3、子传父值

在父组件的render() 的jsx中,自定义事件名,并赋事件方法

在子组件中用**this.props.事件名(子传给父的值)**给父组件传值

4、例子:

子组件

import React from 'react'

export default class List extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            list: [
                { id: 1, name: 'Q' },
                { id: 2, name: 'S' },
                { id: 3, name: 'D' },
                { id: 4, name: 'Y' },
            ]
        }
    }
    langChange(id) {
        console.log('传递的值',id);
        this.props.onChange(id)
    }
    creatList() {
        let { list } = this.state
        let { index } = this.props
        return (list.map(ele => 
            <span
                className={index == ele.id ? 'on' : ''}
                onClick={this.langChange.bind(this,ele.id)}
                key={ele.id}>
                {ele.name}
            </span>
        ))
    }
    render() {
        return (
            <div>
                {/* <div className='language'> */}
                    {this.creatList()}
                {/* </div> */}
            </div>
        )
    }
}
import Child1 from './study/Child1'

export {
    Child1
}

父组件

import React from 'react'

import {Child1} from '@/components/index.js'

export default class TestList extends React.Component{
    constructor(props) {
        super(props)
        this.state = {
            index:1
        }
    }
    listHandle(id) {
        console.log('父接收的值:',id);
        this.setState({index:id})
    }
    render() {
        let { index } = this.state
        return (
            <div>
                <h1>测试父子组件通信</h1>
                <Child1 index={index} onChange={this.listHandle.bind(this)} />
            </div>
        )
    }
}

七、Props

import React from 'react'

// 函数式组件(无状态组件)
// 它没有状态state
// 它没有生命周期,不能使用render
// 它也没有this

// 它唯一好处是性能好,这是react性能优化方式之一

// props是父子之间纽带
// props是只读的,不能改
// props不能赋值给state。props和state没有关系,不能相互赋值。
export default function Child1(props) {
  return(
    <div className='child'>
      <h2>{props.aaa}</h2>
      <h2>{props.bbb}</h2>
      {/* 把父组件传递过的jsx变量渲染出来 */}
      { props.children }
    </div>
  )
}

import Child1 from './study/Child1'
import Child2 from './study/Child2'

export {
    Child1,
    Child2
}
import React from 'react'
import { Child2 } from '@/components'

export default class TestProps extends React.Component {
  constructor(props) {
    super(props)
    // 在这里声明的变量一旦发生变化,视图自动更新(单向绑定)
    this.state = {
      msg: 'hello react',
      bbb: 'bbb'
    }
  }
  // 自定义方法
  changeMsg() {
    let num = Math.random()
    // 用于改变state的,这方法是异步的
    // setState()可以接收第二参数,是一个函数,表示当前异步任务完成的回调
    this.setState({msg: num}, ()=>{
      console.log('更新完成')
    })
  }
  render() {
    let { msg, bbb } = this.state
    msg = msg + ' !!!!'

    return (
      <div>
        <h1>测试state和props</h1>
        <h2>
          {msg}
          <button onClick={this.changeMsg.bind(this)}>改变msg</button>
          {/* aaa是静态传值, bbb是动态传值 */}
          <Child2 aaa='aaa' bbb={bbb}>
            <a href="https://baidu.com">百度</a><br/>
            <a href="https://baidu.com">小米</a>
          </Child2>
        </h2>
      </div>
    )
  }
}

八、表单

受控表单:

value和onChange必须配合使用,那么这种表单就是受控表单

1.单向绑定的

2.表单的value值由state来决定和控制

import React from 'react'

export default class TestFrom extends React.Component{
    constructor(props) {
        super(props)
        this.state = {
            name:'1'
        }
    }
    submit(e) {
        console.log('表单测试');
        console.log(this.state.name);
    }
    nameChange(e) {
        this.setState({
            name:e.target.value,
        })
    }
    render() {
        let {name} = this.state
        return (
            <div style={{margin:"100px auto",width:"300px"}}>
                <input type='text' value={name} onChange={this.nameChange.bind(this)} />
                <button onClick={this.submit.bind(this)}>提交</button>
            </div>
        )
    }
} 

非受控表单:

1.它的value不受state控制

2.React强烈建议,不要使用非受控表单(除文件上传表单外)

//非受控表单
<input type="text" id='ipt'></input>
//获取表单值
document.getElementById('ipt').value

九、状态提升

通常,多个组件需要反映相同的变化数据,这时我们建议将共享状态提升到最近的共同父组件中去。

import React from 'react'

import { LiftA,LiftB } from '@/components';

export default class TestLeft extends React.Component{
    constructor(props) {
        super(props) 
        this.state={
            msg:'1321',
        }
    }
    onPChange(val) {
        this.setState({ msg:val})
    }
    render() {
        let { msg } = this.state
        return(
            <div>
                <h3>状态提升</h3>
                <div>
                    <LiftA msg={msg} />
                    <hr/>
                    <LiftB value={msg} onChange={this.onPChange.bind(this)}/>
                </div>
            </div>
        )
    }
}

import React from 'react'

export default class TestLeft extends React.Component{
    render() {
        let {msg} = this.props
        return(
            <div>
                <h3>组件A</h3>
                <div>
                    <h1>{msg}</h1>
                </div>
            </div>
        )
    }
}

import React from 'react'

export default class TestLeft extends React.Component{
    onChildChange(e) {
        this.props.onChange(e.target.value);
    }
    render() {
        let { value } = this.props
        return(
            <div>
                <h3>组件B</h3>
                <div>
                    <input type='text' value={value} onChange={this.onChildChange.bind(this)}/>
                </div>
            </div>
        )
    }
}

十、组合 vs 继承

React 有十分强大的组合模式。我们推荐使用组合而非继承来实现组件间的代码重用。

包含关系:

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}
function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}      </div>
      <div className="SplitPane-right">
        {props.right}      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />      }
      right={
        <Chat />      } />
  );
}

特例关系:

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
      {props.children}    </FancyBorder>
  );
}

class SignUpDialog extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSignUp = this.handleSignUp.bind(this);
    this.state = {login: ''};
  }

  render() {
    return (
      <Dialog title="Mars Exploration Program"
              message="How should we refer to you?">
        <input value={this.state.login}               onChange={this.handleChange} />        <button onClick={this.handleSignUp}>          Sign Me Up!        </button>      </Dialog>
    );
  }

  handleChange(e) {
    this.setState({login: e.target.value});
  }

  handleSignUp() {
    alert(`Welcome aboard, ${this.state.login}!`);
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值