组件的三种方式
ES 5 组件
ES 6 有状态组件
无状态组件 =>纯组件SFC
无状态组件
无状态的函数创建的组件是无状态组件,它是一种只负责展示的纯组件
function App(props){
console.log(props)
return(
这是一个无状态组件---{props.name}
)
}
// const App = (props)=>(
// 函数式声明--无状态组件 --- {props.name}
// )
优势
代码整洁,易读
无状态,无this
无需绑定
便于测试
性能高
对于这种无状态的组件,使用函数式的方式声明,会使得代码的可读性更好,并能大大减少代码量,箭头函数则是函数式写法的最佳搭档
React中的props和state
React内部分别使用了props, state来区分组件的属性和状态。props用来定义组件外部传进来的属性, 属于那种经过外部定义之后, 组件内部就无法改变。而state维持组件内部的状态更新和变化, 组件渲染出来后响应用户的一些操作,更新组件的一些状态。如果组件内部状态不需要更新,即没有调用过this.setState, 全部通过props来渲染也是没问题的, 不过这种情况不常见
组件的Props也是和组件的UI有关的。他们之间的主要区别是:State是可变的,是组件内部维护的一组用于反映组件UI变化的状态集合;而Props对于使用它的组件来说,是只读的,要想修改Props,只能通过该组件的父组件修改。在组件状态上移的场景中,父组件正是通过子组件的Props, 传递给子组件其所需要的状态
state的修改方法:setState():
this.setState({title: 'React'});
非受控组件
非受控组件即组件的状态改变不受控制
class Demol extends Component {
render(){
return (
)
}
}
在这个最简单的输入框组件里,我们并没有干涉input中的value展示,即用户输入的内容都会展示在上面。如果我们通过props给组件设置一个初始默认值
defaultValue属性是React内部实现的一个属性,目的类似于input的placeholder属性。
ps: 此处如果使用value代替defaultValue,会发现输入框的值无法改变。
受控组件
既然通过设置input的value属性, 无法改变输入框值,那么我们把它和state结合在一起,再绑定onChange事件,实时更新value值就行了。这就是最简单的受控组件模型
组件传值
子组件=>父组件
在子组件标签上绑定属性名,值为function函数,子组件内部通过this.props传送需要传送的值,父组件以函数形参的形式接收
class App extends React.Component{
constructor(props){
super(props)
this.state={
info:""
}
}
render(){
var _this =this
return(
父组件
父组件接受--{this.state.info}
)
}
}
// this.props.name = function
// this.props.name() = function()
// this.props.name(msg) = function(msg)
// msg = msg
class Child extends React.Component{
constructor(props){
super(props)
}
render(){
return(
子组件
)
}
tap(){
this.props.name(this.refs.ipt.value)
}
}
ReactDOM.render( ,document.getElementById('out'))
父组件=>子组件
在子组件标签上绑定属性名,值为父组件需要传递的状态值,子组件内部通过this.props接收
class App extends React.Component{
constructor(props){
super(props)
this.state={
info:""
}
}
render(){
return(
组件传值
父组件
)
}
// 通过ref属性获取DOM节点的内容
tap(){
console.log(this.refs.tit.innerHTML)
}
seed(){
// console.log(this.refs.ipt.value)
this.setState({info:this.refs.ipt.value})
}
}
class Child extends React.Component{
constructor(props){
super(props)
}
render(){
console.log(this.props)
return(
子组件
接收父组件的值--{this.props.name}
)
}
}
ReactDOM.render( ,document.getElementById('out'))
操作DOM
通过ref 获取dom元素,ref给dom添加该属性
通过this.refs.ref的值获取dom
state的初始化和方法的this指针修正
推荐放在构造器里面书写: constructor
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {items: [], text: ''};
}
这里注意:state状态也可以写在外面
constructor(props){
super(props)
}
state={
items:[],
text:""
}
事件传参 onClick={this.tap.bind(this,index)} 数据批量循环展示 使用jsx数组模版
数据加载
1、数据绑定的第一种方式:基于jsx绑定
1、在componentWillMount/componentDidMount 中获取ajax数据 ( 面试题)
2、将得到的数据存入state中
3、在render中直接将state中的数据循环遍历 放在一个jsx的数据模板中
4、循环叠加这个jsx模板 通过{}嵌入到页面中
2、mixins函数(es6 弃用)
1、作用是可以将一些公共的方法写在一个object的方法里面
2、然后通过mixins在组件中声明这个对象的表达式
3、在jsx中 就可以使用this去调用object里面的各个方法
这样实现了react多个组件之间共享一些公共的方法