一、组件
1.1 函数式组件
- 特点:实际上是一个普通函数,但是必须返回React元素(JSX表达式)。
- 两种方式使用函数式组件。
- 不推荐,直接在jsx表达式内调用函数,在控制台上只能看见元素,不能构建出组件结构,对后续优化造成麻烦。
ReactDOM.render(<div>
{MyFuncComp()}
</div>,document.getElementById('root'));

ReactDOM.render(<div>
<MyFuncComp/>
</div>,document.getElementById('root'));

1.2 类组件
- 特点:必须继承React.component(React可省略),并且类组件必须有render方法,并且该方法必须返回React元素(JSX表达式)。
import React, { Component } from 'react'
export default class MyClassComp extends Component {
render() {
return (
<div>
组件内容
</div>
)
}
}
1.3 特别注意
- 组件首字母要大写,为什么?
function MyFuncComp(){
return <h1>组件内容</h1>
}
React.render(<div>
<MyFuncComp/>
</div>,docu,document.getElementById('root'));
function MyFuncComp(){
return <h1>组件内容</h1>
}
const comp = <MyFuncComp/>;
console.log(comp);
React.render(<div>
{comp}
</div>,docu,document.getElementById('root'));
- 首字母大写,生成的React元素type值为函数或类,系统会认为这是一个组件。
 
 
function MyFuncComp(){
return <h1>组件内容</h1>
}
React.render(<div>
<MyFuncComp/>
</div>,docu,document.getElementById('root'));
function MyFuncComp(){
return <h1>组件内容</h1>
}
const comp = <myFuncComp/>;
console.log(comp);
React.render(<div>
{comp}
</div>,docu,document.getElementById('root'));
- 首字母小写,生成的React元素type值为字符串,系统会认为你要创建一个html元素。
 


二、组件属性
组件的属性要使用小驼峰命名法
2.1 函数组件
import React from 'react'
export default function MyFuncComp(props) {
console.log(props);
return (
<h1>函数组件,目前的数字:{props.number}</h1>
)
}
import React from 'react';
import ReactDOM from 'react-dom';
import MyFuncComp from './MyFuncComp';
ReactDOM.render(<div>
<MyFuncComp number='1'/>
<MyFuncComp number='2'/>
<MyFuncComp number='3'/>
<MyFuncComp number='4'/>
</div>,document.getElementById('root'));
- 对于函数组件而言,组件的属性会作为对象的属性,传递给函数的参数(即props)。

2.1 类组件
import React, { Component } from 'react'
export default class MyClassComp extends Component {
constructor(props){
super(props);
console.log(props);
}
render() {
return (
<div>
<h1>函数组件,目前的数字:{this.props.number}</h1>
</div>
)
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import MyClassComp from './MyClassComp';
ReactDOM.render(<div>
<MyClassComp number='7'/>
<MyClassComp number='8'/>
<MyClassComp number='9'/>
</div>,document.getElementById('root'));
- 对于类组件而言,属性会作为对象的属性,传递给构造函数的参数。
三、注意事项
3.1 组件属性值都可以传啥呢
总结一句话:想传啥就传啥
- 布尔值
- 普通对象
- React对象
<MyClassComp enable number={5} obj={{
name: "成哥",
age: 100
}}/>
<MyClassComp number={6} ui={<h2>这是我传递属性</h2>}/>
3.2 之前学习的React元素,本质上就是一个组件(内置组件)
import MyFuncComp from './MyFuncComp';
console.log(<MyFuncComp number='1'/>)
console.log(<div title='jcsdc'>组件内容</div>)

3.3 组件无法改变自身属性
import React from 'react'
export default function MyFuncComp(props) {
props.number = 382748274829;
return (
<h1>函数组件,目前的数字:{props.number}</h1>
)
}

四、React哲学
import React, { Component } from 'react'
export default class MyClassComp extends Component {
render() {
console.log('子组件修改参数前persion值',this.props.obj);
this.props.obj.name='Aziel';
console.log('子组件修改参数后persion值',this.props.obj);
if(this.props.obj){
return (
<>
<p>
姓名:{this.props.obj.name}
</p>
<p>
年龄:{this.props.obj.age}
</p>
</>
);
}
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import MyClassComp from './MyClassComp';
let persion = {
name: "XXXX",
age: 100
};
console.log('渲染前父组件persion值:',persion);
ReactDOM.render(<div>
<MyClassComp number={5} obj={persion}/>
</div>,document.getElementById('root'));
console.log('渲染后父组件persion值:',persion);

- React是一个库,它无法监听深层次的变化,假如你在组件内修改了传入的对象是属性值,那么后面的组件再次使用父组件的这个数据时,这个数据就已经发生了变化,这种写法造成的bug在维护时根本查不出来。
- 假如有一千个组件,有一个组件在使用父组件传入的数据时,发现该数据是错误的,那么其他的任意一个组件都有可能改变了该数据。
- 总之一句话:千万不要在react组件中修改传入的数据,数据属于谁,谁才有权利改动,组件只负责将传入的数据展示就好了,这样在子组件中发现了传入的数据错误,直接找父组件即可。
- 综上所述,React中的数据是自顶而下流动的
|