1.基本使用
创建组件
import React from 'react';class hello extends React.Component {render() {return (<div>这是movie组件</div>);}}export default hello;
使用组件
import React from 'react';import ReactDOM from 'react-dom';import './index.css';import * as serviceWorker from './serviceWorker';import Hello from "@/components/hello"ReactDOM.render(<Hello></Hello>,document.getElementById('root'));serviceWorker.unregister();
2.state
注意点:
我们不能够直接修改state 比如this.state.msg = “”这是错误,因为他不会触发页面刷新 所以我们应该通过this.setState方法来更新数据
setState有可能是异步的,只要在react机制能够处理到的地方都是异步的,在react机制处理不到的地方都是同步的(比如setInterval setTimeout)
因为setState可能是异步的,所以我们想要setState之后立马获取最新的数据,我们可以使用setState的第二个参数(箭头函数)
因为setState可能是异步的,所以我们不能基于原来的state来修改当前的state,而是应该使用箭头函数作为setState的第一个参数
只要我们调用setState方法就会触发页面刷新,不管数据在页面有没有使用,也不管数据有没有发生变化,因为内部会调用batchingupdate方法来实现页面更新。对应的我们可以使用shouldComponetUpdate方法来做性能优化
setState会把新的state合并到原来的state中
react中不能直接修改state,因此需要将之设置只读
import React from 'react';const txtState={msg:"这里是组件自己特有的信息"}//获取 txtState类型type Istate=Readonly<typeof txtState>//设置为只读//这里的React.Component<p,s>,p这里的范型表示对props进行约定,s对state进行约定//将Istate作为它的类型给范型class movies extends React.Component<IProps,Istate> {//定义state的类型state:Istate=txtStaterender() {return (<div>{this.state.msg}</div>);}}export default movies;
修改state,使用setstate
//定义类型,Readonly表示只读type IProps = Readonly<{name: string;age: number;}>;const txtState = { msg: "这里是组件自己特有的信息" ,count:1};//获取 txtState类型type Istate = typeof txtState;class movies extends React.Component<IProps, Istate> {//定义state的类型state: Istate = txtState;handleClick = () => {//这样来修改state中的数据this.setState({msg:"234"})};render() {return (<div>数据是: {this.state.msg}<button onClick={this.handleClick}>修改数据</button></div>);}}
state可能是异步的
我们在使用setState时无法基于原来的数值来推导当前的数值
如何在前一次修改了state的基础上对state进行修改?
import React from "react";//定义类型,Readonly表示只读type IProps = Readonly<{name: string;age: number;}>;const txtState = { msg: "这里是组件自己特有的信息" ,count:1};//获取 txtState类型type Istate = typeof txtState;//这里的React.Component<p,s>,p这里的范型表示对props进行约定,s对state进行约定//将Istate作为它的类型给范型class movies extends React.Component<IProps, Istate> {//定义state的类型state: Istate = txtState;handleClick1=()=>{this.setState((state:Istate,props:IProps)=>{return{count:state.count+1}})//这里的state和props都是当前最新的statethis.setState((state:Istate,props:IProps)=>{return{count:state.count+1}})}render() {return (<div>当前数量是:{this.state.count}<button onClick={this.handleClick1}>增加数据</button></div>);}}export default movies;
在修改state之后如何立刻如何获得最新数据,this.state第二个参数是一个回调函数,在这个回调函数中可以拿到最新的数据
this.setState((state:Istate,props:IProps)=>{return{count:state.count+1}},()=>{//这里可以获取修改好的最新数据,不然这里的setstate是异步的无法得到最新的数据console.log(this.state.count,"xxxxxxxxxxx")})
setstate会把当前的值和原来的state进行合并得到一个新的值
只要调用setstate,就会触发页面的重新渲染,不管这个state在页面有没有使用过,也不管这个state有没有发生变化。
手动决定是否渲染页面,利用shouldComponentUpdate
//需不需要更新页面,如果该方法返回false不会更新页面,如果返回结果是true会更新页面//nextState将要更新的值,做性能优化shouldComponentUpdate(nextProps:IProps,nextState:Istate){if(JSON.stringify(this.state)===JSON.stringify(nextState)){return false}else{return true}}
setState会触发batchingUpdate方法来触发页面更新
** setState的实现过程**
import React from "react";//定义类型,Readonly表示只读type IProps = Readonly<{name: string;age: number;}>;const txtState = { msg: "这里是组件自己特有的信息" ,count:1};//获取 txtState类型type Istate = {msg:string,count:number,name?:string};//这里的React.Component<p,s>,p这里的范型表示对props进行约定,s对state进行约定//将Istate作为它的类型给范型class movies extends React.Component<IProps, Istate> {//定义state的类型state: Istate = txtState;handleClick = () => {//这样来修改state中的数据this.setState({msg:"234"})};handleClick1=()=>{//state可能是异步的this.setState((state:Istate,props:IProps)=>{return{count:state.count+1}},()=>{//这里可以获取修改好的最新数据,不然这里的setstate是异步的无法得到最新的数据console.log(this.state.count,"xxxxxxxxxxx")})}handleClick2=()=>{this.setState((state,props)=>{return{name:"叶枫"}},()=>{console.log(this.state)})}//这里的state和props都是当前最新的state// this.setState((state:Istate,props:IProps)=>{// return{// count:state.count+1// }// })//需不需要更新页面,如果该方法返回false不会更新页面,如果返回结果是true会更新页面//nextState将要更新的值,做性能优化shouldComponentUpdate(nextProps:IProps,nextState:Istate){if(JSON.stringify(this.state)===JSON.stringify(nextState)){return false}else{return true}}render() {console.log("render函数执行了")return (<div>{/* 无法直接在这里进行.拿到对应的属性 */}{/* {JSON.stringify(this.props)} */}{this.props.name}{this.props.age}{this.state.msg}<br></br>当前数量是:{this.state.count}<button onClick={this.handleClick}>修改数据</button><button onClick={this.handleClick1}>增加数据</button><button onClick={this.handleClick2}>点我可修改姓名</button></div>);}}export default movies;
