组件分为函数组件和Class组件,理解每个组件的用法和接收外部数据(Props)以及声明读写内部数据
一、元素和组件声明
元素:const div = React.createElement(‘div’)
组件:const Div = ()=>React.createElement(‘div’)
二、组件分类
1. 组件声明与使用
函数组件
// 声明
function Hello(props){ return <h1>Hello,{props.name}</h1>}
//使用<Hello name="皮卡丘"></Hello>
类组件
// 声明
Class Hello extends React.Component { render(){ return <h1>Hello,{this.props.name}</h1> }}// 使用<Hello name="小明"></Hello>
以上两种组件的 会被翻译成React.createElement(),
**如果是原生标签,如div,则会变成字符串:
**React.createElement('div')****
如果是组件标签,如Hello,则会变成函数:
React.createElement(Hello)****
2. 组件如何使用 props (外部数据)
props 只能读,不能写
父组件
function App(){ Return ( <div>
父组件 <Hello name="小明"/> </div> )}
传入字符串使用 " " 例如。
传入Js变量使用 { } 例如<Hello name={ n }/>
函数组件 接收props
function Hello(props){ return <h1>Hello,{props.name}</h1>}
类组件 接收props
Class Hello extends React.Component { render(){ return <h1>Hello,{this.props.name}</h1> }}
3.组件使用内部数据
函数组件
function Hello(props){
//析构写法 数组接收两个值[读的数据,写的函数] const [n,setN] = React.userState(0) return (
<h1 >Hello,{props.name}</h1> <button onClick={()=>setN(n+1)}>+1</button> )
}
setN不会马上改变n ,setN永远不会改变n,只会产生一个新的n,setState(setN)不会自动合并数据,需要手动复制数据 ...state 。
类组件
Class Hello extends React.Component {
// 初始化
construcor(){
Super();
this.state = {n:0}
}
add(){
this.setState({n:this.state +1})
/* this.setState 是一个异步的过程,过一会会改变n,
会自动沿用上一次的this.state第一层属性,最好改写为
this.setState(state=>{ const n = state.n +1 return {n} })
这样写的好处是能区分 新(n)、旧(n)数据 */
}
render(){
return (<h1>Hello,{this.state.n}<button onClick={()=>this.add()}>+1</button></h1>)
}
}
使用this.setSate的时候不要在原有的对象上修改,最好使用一个新的对象,这是react的理念(数据不可变)
三、事件绑定
可用写法
<button onclick={()=>this.addN()}> n+1 </button>
<button onclick={this.addN.bind(this)}> n+1 </button>
不可用写法
<button onclick={this.addN}> n+1 </button>
这种写法不推荐是使用是因为他的this,可能会变成window。原因是当用于点击button的时候 react 运行的是 button.onClick.call(),这时的call并没有传入参数,所以这时候this === null,这时候addN的this为undefind ,为nudefind 就会变成window
最终推荐的写法为函数使用箭头函数
Class Hello extends React.Component {
// ...
addN()=()=>{
...
}
render(){
return (<button onClick={this.addN}>+1</button>)
}
}