关于组件--React
组件按照页面结构可以分成,头部、底部、内容部分。这样就可以写三个组件。
组件内部还可以包含下一级组件,
比如头部,可以包含登录,注册等组件。
底部 可以 包含一些链接等。
内容部分可以包含表单组件、按钮组件等一些功能组件。
组件的好处很多,
有利于细化UI逻辑,不同组件控制不同的功能点。
有利于代码复用,不同页面使用相同的组件。
有利于人员分工,不同工程师负责不同的组件。
React 的核心概念就是组件。
JSX语法特点就是 凡是使用JavaScript的值的地方,都可以使用类似的HTML的语法。
有两个注意点:1、标签必须是闭合的。2、顶层只能有一个标签,即只有一个根元素。
JSX语法允许JavaScript和HTML混写。
1 const element = ( 2 <h1> 3 Hello, {formatName(user)}! 4 </h1> 5 );
虽然输出 JSX 代码的函数就是一个 React 组件,但是这种写法只适合那些最简单的组件。更正式、更通用的组件写法,要使用 ES6 类(class)的语法。
1 import React from 'react' 2 3 class ShoppingList extends React.Component { 4 render() { 5 return ( 6 <div> 7 <h1>shopping list for {this.props.name} </h1> 8 <ul> 9 <li>跑鞋</li> 10 <li>压缩裤</li> 11 <li>滑板</li> 12 </ul> 13 <div>this.props.children: {this.props.children}</div> 14 </div> 15 ) 16 } 17 } 18 19 export default ShoppingList;
组件内部,所有参数都放在this.props这个属性上面。
this.props
对象有一个非常特殊的参数this.props.children
,表示当前组件“包裹”的所有内容。
React 规定,组件的内部状态记录在this.state
这个对象上面。
生命周期
组件运行过程中存在不同阶段,React 为这些阶段提供了钩子方法,允许开发者自定义每个阶段自动执行的函数。这些方法统称为生命周期方法(lifecycle methods)。
其中componentDidMount()
、componentWillUnmount()
和componentDidUpdate()
就是三个最常用的生命周期方法。其中,componentDidMount()
会在组件挂载后自动调用,componentWillUnmount()
会在组件卸载前自动调用,componentDidUpdate()
会在 UI 每次更新后调用(即组件挂载成功以后,每次调用 render 方法,都会触发这个方法)。
还有3个不常用的:
shouldComponentUpdate(nextProps, nextState)
:每当this.props
或this.state
有变化,在render
方法执行之前,就会调用这个方法。该方法返回一个布尔值,表示是否应该继续执行render
方法,即如果返回false
,UI 就不会更新,默认返回true
。组件挂载时,render
方法的第一次执行,不会调用这个方法。static getDerivedStateFromProps(props, state)
:该方法在render
方法执行之前调用,包括组件的第一次记载。它应该返回一个新的 state 对象,通常用在组件状态依赖外部输入的参数的情况。getSnapshotBeforeUpdate()
:该方法在每次 DOM 更新之前调用,用来收集 DOM 信息。它返回的值,将作为参数传入componentDidUpdate()
方法。
受控与非受控组件
非受控组件:
import React from 'react' const MyInput = ({onChange}) => ( <input onChange={onChange} /> ) class Demo extends React.Component { onTextChange = (event) => { console.log(event.target.value); } onTextReset = () => { // 这里该怎么做? // 拿到 input 的值,然后 = '' ? } render() { return ( <div> <MyInput onChange={this.onTextChange} /> <button onClick={this.onTextReset}>Reset</button> </div> ) } } export default Demo;
看起来,要修改MyInput中的值并不容易,对于这种不能直接控制状态的组件,我们称之为“非受控组件”。
受控组件:
将上面代码进行修改
1 import React from 'react' 2 3 const MyInput = ({value = '', onChange}) => ( 4 <input value={value} onChange={onChange} /> 5 ) 6 class Demo extends React.Component { 7 state = { 8 text: '', 9 } 10 onTextChange = (event) => { 11 console.log(event.target.value); 12 this.setState({text: event.target.value}) 13 } 14 onTextReset = () => { 15 // 这里该怎么做? 16 // 拿到 input 的值,然后 = '' ? 17 this.setState({text: ''}) 18 } 19 render() { 20 return ( 21 <div> 22 <MyInput value={this.state.text} onChange={this.onTextChange} /> 23 <button onClick={this.onTextReset}>Reset</button> 24 </div> 25 26 ) 27 } 28 } 29 30 export default Demo;
这样 MyInput 的输入就完全由value值决定。
“受控”与“非受控”两个概念,区别在于这个组件的状态是否可以被外部修改。一个设计得当的组件应该同时支持“受控”与“非受控”两种形式,即当开发者不控制组件属性时,组件自己管理状态,而当开发者控制组件属性时,组件该由属性控制。而开发一个复杂组件更需要注意这点,以避免只有部分属性受控,使其变成一个半受控组件。