说实话React的学习并不简单,虽然做了一些知识学习,但是还没有到那种自己想实现一个功能的时候就能立马写出代码的能力;所以现在还是需要多巩固,多写代码,然后今天参考了官网上的文档,自己又照葫芦画瓢实现上面的一些例子。
首先说一下“”组件“吧
个人理解就是封装好的具有一定功能,属性和外形的一个"类"。例如一个对话框可以定义成一个组件。
定义组件的最简单的方法是编写JavaScript函数;(这里需要注意的就是所有组件名的开头字母必须大写)
function Welcome( ) { return <h1>Hello</h1>; } ReactDOM.render( <Welcome />,document.getElementById('app') );
这个我们可以看成是一个Welcome组件,它的外形它的返回值,我们可以看到是<h1>Hello</h1>,这里面它没有其他功能和属性,只是单纯一个文本的组件;我们再通过ReactDom.render获取Welcome组件的返回值,然后将其转换为HTML代码,插入我们的真实DOM中,呈现在我们面前。(说实话,没有太多意思,还不如我们自己在html里面手写)
当然这个不是React开发出来的初衷,它主要是在UI渲染过程中,通过在虚拟DOM中的微操作来实对现实际DOM的局部更新。(重点是数据更新更快)
我们上面的例子只是一个”静态的组件“,所以参考价值不大。
下面这个例子比上面一个”丰富“了一点,它多了一个形参props;这其实是一个对象,里面包含了这个组件中所有的属性,比如name,className,id等等,还有一些自己定义的属性。当然,也提到过它和state的区别,props专一,state花心;(props是只读的,我们不能去修改它,而state可以)
function Welcome(props) { return <h1>Hello,{props.name}</h1>; } const element = <Welcome name="Sara" />; ReactDOM.render( element,document.getElementById('app') );
这就相当于一个"渲染组件",多了一个渲染的功能,能够更新显示的内容。
当然现在上面这些组件的定义都是用function来定义的,es6中我们其实可以用class来定义
class Welcome extends React.Component{
constructor() {
super();
}
render(){
return (
<h1>Hello {this.props.name}</h1>
)
}
}
ReactDOM.render(
<Welcome name="world"/>,document.getElementById('app')
);
只不过这些简单的小组件我们完全可以用function的那种方式来定义,官网上的例子也是这样,仅供参考。(我这里打印了一下用class定义的组件,构造函数是Function)
然后说一下组件的嵌套,也就是我们的父子组件。
下面的例子就是我们有2个子组件<User>和<Guest>,将其嵌入到我们的<Greeting>组件里面,然后再用一个props属性来选择返回哪个子组件,这里是把前面的结合了起来,其实也可以把2个子组件都显示出来,不过我们需要返回的时候需要把2个子组件用一个DOM节点包裹起来,比如<div>
function User(props) { return <h1>welcome back!</h1> } function Guest(props) { return <h1>please sign up!</h1> } class Greeting extends React.Component { constructor(props) { super(props); } render(){ if(this.props.islogin) { return <User/> } else{ return <Guest/> } } } ReactDOM.render( <Greeting islogin={true} />,//true和false要用{ }包裹起来 document.getElementById('app') );
上面我们都是通过props来实现功能的,再来一个例子通过改变state的值来进行显示操作;
function WarningBanner(props) { if (!props.warn) { return null; } return ( <div className="warning"> Warning! </div> ); } class Page extends React.Component { constructor(props) { super(props); this.state = {showWarning: true} } handleToggleClick() { this.setState(prevState => ({ showWarning: !prevState.showWarning })); } render() { return ( <div> <WarningBanner warn={this.state.showWarning} /> <button onClick={()=>{this.handleToggleClick()}}> {this.state.showWarning ? 'Hide' : 'Show'} </button> </div> ); } } ReactDOM.render( <Page />,document.getElementById('app') );
state也是一个对象,我们可以通过this.state.xxx获得具体的某个属性,这个属性是可以修改的(this.props.xxx是不可以修改的)。在ES6中它是定义在constructor中;
props主要是用来初始化属性,而state是用来更新属性。
setState(nextState,callback)
A.第一个参数可以是一个对象,就是设置的状态
简单的对象用法:
this.setState ( { showWarning : 'false '});
B.第一个参数也可以接收一个函数,这个函数接受两个参数,第一个参数表示上一个状态值,第二参数表示当前的 props,
this.setState((prevState,props) => ({
//do something here
}));
所以我们这里就是:
this.setState(prevState => ({ showWarning: !prevState.showWarning })) }这里的prevState就是我们前一个的状态对象this.state,我们每点击一次就去改变showWarning的状态
需要注意一下就是:this.setState 是在 render 时,,state 才会改变调用的,,也就是说,,setState 是异步的.。组件在还没有渲染之前。 this.setState 还没有被调用。这么做的目的是为了提升性能, 在批量执行 State 转变时让 DOM 渲染更快。
我们可以打印一下看看:
handleToggleClick() { this.setState(prevState => ({ showWarning: !prevState.showWarning }),()=>console.log(`回调函数:${this.state.showWarning}`)); console.log(`调用后:${this.state.showWarning}`) }我们如果想得到我们修改后的数据,只能到render中获得,或者回调函数中去获得。