react组件
React 组件基本由三个部分组成,
- 属性 props
- 状态 state
- 生命周期方法
React的数据是自顶向下单向流动的,即从父组件到子组件中,组件的数据存储在props和state中。
(1) props属性
我理解的props意义是用来组件传值
React的核心思想就是组件化思想,页面会被分割成一些独立的、可复用的组件。从原始的react来看,其实一个类函数,而这个类函数通过一个参数作为输入值,这个参数就是props。
所以可以理解为,props是从外部传入组件内部的数据(对于父子组件同样适用,从父组件向子组件传递的数据)。
以todoList为例子,下面是子组件,todoitem
- 子组件使用父组件传递过来的数据
import React from 'react';
class TodoItem extends React.Component{
constructor(props){
super(props)
}
render(){
var {id, name, isCompleted} = this.props
return(
<div>
<P>name</P>
<P>this.props.id</P>
<P>this.props.name</P>
<P>this.props.isCompleted</P>
</div>
)
}
}
export default TodoItem;
父组件:
import React from 'react'
import TodoItem from './TodoItem'
class TodoList extends React.Component{
render(){
return (
<ul>
{
this.props.todos.map((todo,index)=>{
return (
<TodoItem
key={index}
name={todo.name}
isCompleted={todo.isCompleted}
id={todo.id}>
</TodoItem>
)
})
}
</ul>
)
}
}
export default TodoList;
在父组件中调用子组件,并将数据传递给子组件。子组件通过constructor构造函数定义props,并在render函数中可以使用this.props.XXX直接访问父组件传递过来的数据
注意:
this.props是一个对象,这个对象包含了所有你对这个组件的配置,比如父组件设置了name,isCompleted和id属性,就可以通过this.props.xxx获取。
- 父组件操作子组件上的数据
子组件通过函数将数据传给父组件
import React from 'react';
//import classnames from 'classnames'
class TodoItem extends React.Component{
constructor(props){
super(props)
//如果没有使用箭头函数定义则需要在构造函数中进行声明
//this.handelDelete = this.handelDelete.bind(this)
}
handleDelete=()=>{
this.props.removeTask(this.props.id)
}
render(){
}
return(
<li>
<button className="close" onClick={this.handleDelete}</button>
</li>
)
}
}
export default TodoItem;
父组件,定义函数对子组件进行操作:
import React from 'react'
import TodoItem from './TodoItem'
//import classnames from 'classnames'
class TodoList extends React.Component{
const removeTask()=>{
//xxx
}
render(){
return (
<ul style={{listStyle:'none',width:'400px'}}>
{
this.props.todos.map((todo,index)=>{
return (
<TodoItem
key={index}
removeTask={this.props.removeTask}
</TodoItem>
)
})
}
</ul>
)
}
}
export default TodoList;
注意:
props经常被用来渲染组件和初始化状态,当一个组件被实例化之后,它的props是只读的,不可改变的。如果props在渲染过程中可以被改变,会导致这个组件显示的形态变得不可预测。只有通过父组件重新渲染的方式才可以把新的props传入组件中。
当大量子组件公用一个父组件,且之间互相传值时,如果单纯的时候props进行传递时非常麻烦的,所以产生了Redux
总结
props是一个从外部传进组件的参数,主要作为就是从父组件向子组件传递数据,它具有可读性和不变性,只能通过外部组件主动传入新的props来重新渲染子组件,否则子组件的props以及展现形式不会改变。
(2)状态 state
前面有说到,react是一个组件,一个组件的显示形态可以由数据状态和外部参数来决定,props是外部参数,那么数据状态就是state。
export default class ItemList extends React.Component{
constructor(){
super();
this.state = {
itemList:'一些数据',
}
}
render(){
return (
{this.state.itemList}
)
}
}
在组件初始化的时候,通过this.state给组件设置了一个初始state,在第一次render的时候这个设置好的数据 就会来渲染组件。
setState
state不同于props的一点就是state是可以被改变的
改变方法是this.setState()
,而不是直接赋值。
注意:
当我们调用this.setState方法时,React会更新组件的数据状态state,并且重新调用render方法,也就是会对组件进行重新渲染。
export default class ItemList extends React.Component{
constructor(){
super();
this.state = {
name:'axuebin',
age:25,
}
}
componentDidMount(){
this.setState({age:18})
}
}
setState可以接受一个对象或者函数来作为自己的第一个参数。只需哟传入需要更新的部分即可,不需要传入整个对象。
在执行完上段代码后,state应该是{name:‘axuebin’,age:18}。
同时,setState还可以接受第二个参数(函数),他会在setState调用完并且在组件开始重新渲染时被调用,可以用来监听渲染是否完成:
this.setState({
name:'xb'
},()=>console.log('setState finished'))
总结
- state的作用是用于组件保存、控制和修改自己的状态;
- 只能在constructer构造函数中初始化;
- 属于组件的私有属性,不能通过外部访问和修改。只能通过this.setState来修改,修改state属性会导致组件的重新渲染。
区别
state | props |
---|---|
组件自己管理数据,自己控制状态 | 外部传入的数据参数 |
可变 | 不可变 |
有state的叫做有状态组件 | 无state的叫做无状态组件 |