1.属性(props)初始
状态state都是组件内部写的,也就是A组件内的state就只能A组件里面用,其他组件复用不了。因此属性props就可以。
比如一个导航栏,首页有,购物车有,我的有,他们三个其实用的是同一个导航栏组件,但是三个页面的导航栏细节部分又不一样,比如有些左边有按钮,有些是右边有按钮,因此这肯定是需要传参数去控制的,不然同一个导航栏组件怎么不一样呢对吧。
import React, { Component } from 'react'
import Navbar from './navbarComponent/navbar'export default class App extends Component {render() {return (<div><div><h2>首页</h2><Navbar title="首页"/></div><div><h2>购物车</h2><Navbar title="购物车"/></div><div><h2>列表</h2><Navbar title="列表"/></div></div>)}
}
import React, { Component } from 'react'export default class Navbar extends Component {render() {return (<div>Navbar</div>)}
}
给组件里面传了参数,因此需要组件接收才行
this.props
export default class Navbar extends Component {render() {console.log(this.props);return (<div>Navbar-{this.props.title}</div>)}
}
-[]
注意:
(1) 在组件上通过key=value 写属性,通过this.props获取属性,这样组件的可复用性提高了。 (2) 注意在传参数时候,如果写成isShow="true" 那么这是一个字符串 如果写成isShow={true} 这个 是布尔值
2.接收属性做验证 propTypes
引入react封装好的库
import Proptypes from 'prop-types' //此处from前面的名字你自己定义
两种写法:放class外面和里面 推荐放里面,放里面需要写static
import React, { Component } from 'react'import Proptypes from 'prop-types' //此处from前面的名字你自己定义 export default class Navbar extends Component {state = {}//类接收属性 所以类去控制static propTypes = {title: Proptypes.string,showneed: Proptypes.bool}render() {console.log(this.props);return (<div>Navbar-{this.props.title}-{this.props.showneed}</div>)}
}//类接收属性 所以类去控制
// Navbar.propTypes = {
// title: Proptypes.string,
// showneed: Proptypes.bool
// }
3.默认属性
就是这个属性如果没传值,就用默认值,如果传值了,就用传的值,会自动覆盖掉默认值。
Navbar.defaultProps={showneed:true
}
放里面去 加static
对于函数式组件,属性不是通过this.props ,而是通过一个形参,形参名字随便取
4.状态VS属性
相似点:都是纯js对象,都会触发render更新,都具有确定性(状态/属性相同,结果相同)
不同点:
1. 属性能从父组件获取,状态不能
2. 属性可以由父组件修改,状态不能
3. 属性能在内部设置默认值,状态也可以,设置方式不一样
4. 属性不在组件内部修改,状态要在组件内部修改
5. 属性能设置子组件初始值,状态不可以
6. 属性可以修改子组件的值,状态不可以
state 的主要作用是用于组件保存、控制、修改自己的可变状态。 state 在组件内部初始化,可以被 组件自身修改,而外部不能访问也不能修改。你可以认为 state 是一个局部的、只能被组件自身控制 的数据源。 state 中状态可以通过 this.setState 方法进行更新, setState 会导致组件的重新渲 染。
props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参 数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props ,否则组件的 props 永远保持 不变。
没有 state 的组件叫无状态组件(stateless component),设置了 state 的叫做有状态组件 (stateful component)。因为状态会带来管理的复杂性,我们尽量多地写无状态组件,尽量少地写有 状态的组件。这样会降低代码维护的难度,也会在一定程度上增强组件的可复用性。
5.表单中的受控组件与非受控组件
5.1 非受控组件
React要编写一个非受控组件,可以 使用 ref 来从 DOM 节点中获取表单数据,就是非受控组件。 例如,下面的代码使用非受控组件接受一个表单的值:
class NameForm extends React.Component {constructor(props) {super(props);this.handleSubmit = this.handleSubmit.bind(this);this.input = React.createRef();}handleSubmit(event) {alert('A name was submitted: ' + this.input.current.value);event.preventDefault();}render() {return (<form onSubmit={this.handleSubmit}><label>Name:<input type="text" ref={this.input} /></label><input type="submit" value="Submit" /></form>);}
}
因为非受控组件将真实数据储存在 DOM 节点中,所以在使用非受控组件时,有时候反而更容易同时集 成 React 和非 React 代码。如果你不介意代码美观性,并且希望快速编写代码,使用非受控组件往往可 以减少你的代码量。否则,你应该使用受控组件。
默认值
在 React 渲染生命周期时,表单元素上的 value 将会覆盖 DOM 节点中的值,在非受控组件中,你经 常希望 React 能赋予组件一个初始值,但是不去控制后续的更新。 在这种情况下, 你可以指定一个 defaultValue 属性,而不是 value 。
render() {return (<form onSubmit={this.handleSubmit}><label>Name:<input defaultValue="Bob" type="text" ref={this.input} /></label><input type="submit" value="Submit" /></form>);
}
同样, <input type="checkbox"> 和 <input type="radio"> 支持 defaultChecked , <select>
和 <textarea> 支持 defaultValue 。
5.2 受控组件
handleChange(event) {this.setState({value: event.target.value});}<input type="text" value={this.state.value} onChange={this.handleChange}
由于在表单元素上设置了 value 属性,因此显示的值将始终为 this.state.value ,这使得 React 的 state 成为 唯一数据源。由于 handlechange 在每次按键时都会执行并更新 React 的 state,因此显示的值将随着用户输入而 更新。 对于受控组件来说,输入的值始终由 React 的 state 驱动。你也可以将 value 传递给其他 UI 元素,或者通过其他 事件处理函数重置,但这意味着你需要编写更多的代码。
注意: 另一种说法(广义范围的说法),React组件的数据渲染是否被调用者传递的 props 完全控制,控制则 为受控组件,否则非受控组件。