美文网首页
react(二)

react(二)

作者: Kiki_Q | 来源:发表于2020-11-04 15:18 被阅读0次

一、

1.当组件的state或者props发生改变的时候,render函数就会重新执行;当父组件的render函数被运行时,他的子组件的render都将被重新运行
2.react视图更新原理:
image.png
image.png

优点:1.提升性能2.跨端应用的实现reactNative
虚拟dom:1.同层比对

3.生命周期:
image.png
4.prevState的使用
1.组件中只能通过setState改变state的值,其他直接赋值等改变state的方式都将不被允许
2.setState接收第二个回调函数
3.prevState接收的是变化钱的值
4.className

this.setState((prevState) =>({
  list:[...prevState.list,prevState.inputValue],
  inputValue: ''
}), () => { console.log(this.ul.querySelectorAll('div').length) })

二、使用Charles进行接口数据模拟

1.下载工具
2.配置


image.png
image.png

三.父组件

1.react中操作dom使用ref={(input) => {this.input = input}}
2.通过bind(this)来绑定this的指向
3.UI组件的使用
4.生命周期方法的使用


import React, { Component } from 'react'
//按需引入antd组件
import 'antd/dist/antd.css'
import { Input,Button,List} from 'antd'

class TodoList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue:'',
            list:[]
        }
        this.handleInputChange =  this.handleInputChange.bind(this)
        this.handleBtnClick=  this.handleBtnClick.bind(this)
        this.handleItemDelete=  this.handleItemDelete.bind(this)
    }

      //在组件即将被挂在到页面的时候自动执行
      componentWillMount(){}

      render(){
          return(
              <Fragment>
                      <div>
                          <label htmlFor="insertArea">输入内容</label>

                          <input id="insertArea" className='input' value={this.state.inputValue} onChange= {this.handleInputChange} ref={(input) => {this.input = input}}/>
                          <button onClick={this.handleBtnClick}>提交</button>
                      </div>
                      <ul> { this.getTodoItem() }</ul>
              <Fragment>
          )
      }
}

//组件被挂载到页面之后,自动被执行
componentDidMount() {}
//组件被更新之前,他会自动被执行
shouldComponentUpdate(){}
//如果被更新之前,它会自动执行,但是她在shouldComponentUpdate之后,
//如果shouldComponentUpdate返回false,这个函数不会被执行
componentWillUpdate() {}

//将代码做部分分离
getTodoItem() {
    return this.state.list.map( (item,index) => { 
           return (
            <TodoItem key={item} content={item} index={index} deleteItem={this.handleItemDelete}/>
          )
    } )
}

handleInputChange(){
    const value = this.input.value;
    this.setState( () => { inputValue:value } )
}

handleBtnClick() {
      this.setState((prevState) =>({
        list:[...prevState.list,prevState.inputValue],
        inputValue: ''
      }), () => { console.log(this.ul.querySelectorAll('div').length) })
}

handleItemDelete(index) {}

四.子组件

import React, { Component } from 'react';
import PropTypes from 'props-types';//参数约束

class TodoItem extends Component {
  constructor() {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
 
//代码优化
//由于父组件的更新就会引发子组件的更新,但是这样损耗了性能
//通过shouldComponentUpdate来判断,只有该组件相关的参数发生更新再更新
shouldComponentUpdate(nextProps,nextState){
    if(nextProps.content !== this.props.content) {
        return true;
    }else{
      return true
    }
}

  render(){
    const { content,test } = this.props; //代码优化
   // return <div onClick={ this.handleClick }>{ this.props.content }</div>
    return (<div onClick={ this.handleClick }>{ test } - { content }</div>)
  }
  handleClick(){
      const { deleteItem, index } = this.props;
      deleteItem(index);
  }

//一个组件要从父组件接收参数
//只要父组件的render函数被执行了,子组件的这个生命周期函数就会被执行
//如果这个组件第一次存在于父组件中,不会执行
//如果这个组件之前已经存在于父组件中,才会执行
  componentWillReceiveProps() {}
}

TodoItem.propTypes = {
      test:PropTypes.string.isRequired,//PropTypes.oneOfType(PropTypes.number,PropTypes.func)
}
TodoItem.defaultProps = {
      test:'hello world'
}

export default TodoItem

五、App.js

important React, { Component, Fragment } from 'react';
important { CSSTransition, TransitionGroup } from 'react-transition-group'
important './style.css'

class App extends Component {
    constructor((props){
        super(props);
        this.state = {
            list: []
        }
        this.handleAddItem = this.handleAddItem.bind(this);
    }

    render() {
        return (
          <Fragment>
            <TransitionGroup>
                this.state.list.map((item,index) => {
                      return ( 
                        <CSSTransition timeout = {1000} classNames='fade' unmountOnExit
                        onEntered={(el) => {el.style.color='blue'}  appear={true} key={index}}>
                          <div>{item}</div>
                        </CSSTransition>
                      )
                })
           <TransitionGroup>
         <Fragment>
        )
    }
}
react中的css动画

1.原生


image.png
image.png

2.通过组件 react-transition


image.png
image.png
image.png

六、Redux

1.redux的工作流程


image.png

2.引入


image.png
引入redux调试工具到代码需要做以下配置
image.png

3.引入redux后的TodoList

1.引入store,删除了本文件的state


import React, { Component } from 'react'
//按需引入antd组件
import 'antd/dist/antd.css'
import { Input,Button,List} from 'antd';
import store from './store';//

class TodoList extends Component {
    constructor(props) {
        super(props);
        this.state = store.getState();

        this.handleInputChange =  this.handleInputChange.bind(this)
        this.handleBtnClick=  this.handleBtnClick.bind(this)
        this.handleItemDelete=  this.handleItemDelete.bind(this);

        store.subscribe(this.handleStoreChange);
    }

      //在组件即将被挂在到页面的时候自动执行
      componentWillMount(){}

      render(){
          return(
              <Fragment>
                      <div>
                          <Input placeholder='todo info'  className='input' value={this.state.inputValue} onChange= {this.handleInputChange} ref={(input) => {this.input = input}}/>
                          <Button type='primary' onClick={this.handleBtnClick}>提交</Button>
                      </div>
                      <List
                          style={{marginTop:'10px',width:"300px"}}
                          bordered
                          dataSource={this.state.list}
                          renderItem={ item => (<List.Item>{item}</List.Item>) }
                      />
                     // <ul> { this.getTodoItem() }</ul>
              <Fragment>
          )
      }
}

//组件被挂载到页面之后,自动被执行
componentDidMount() {}
//组件被更新之前,他会自动被执行
shouldComponentUpdate(){}
//如果被更新之前,它会自动执行,但是她在shouldComponentUpdate之后,
//如果shouldComponentUpdate返回false,这个函数不会被执行
componentWillUpdate() {}

handleInputChange(e){
    //1.
   // const value = this.input.value;
   // this.setState( () => { inputValue:value } )

   //2.
   // const action = { type:'change_input_value',value:e.target.value }
    //store.dispatch(action);

    //3.使用actionCreator.js统一创建action
    const action = getInputChangeAction(e.target.value);
    store.dispatch(action);
}

handleStoreChange() {
    this.setState(store.getState());
}

handleBtnClick() {
    //  this.setState((prevState) =>({
    //    list:[...prevState.list,prevState.inputValue],
    //    inputValue: ''
   //   }), () => { console.log(this.ul.querySelectorAll('div').length) })

    //ActionTypes的拆分
    const action = { type:ADD_TODO_ITEM };
    store.dispatch(action);
}

handleItemDelete(index) {}

export default TodoList;

4.actionTypes.js的使用


image.png

5.reducer.js的使用


image.png
6.使用actionCreator.js统一创建action
image.png

7.store的几个方法


image.png

七、容器组件和UI组件(傻瓜组件)

容器组件

 class TodoList extends Component {
    constructor(props) {
        super(props);
        this.state = store.getState();

        this.handleInputChange =  this.handleInputChange.bind(this)
        this.handleBtnClick=  this.handleBtnClick.bind(this)
        this.handleItemDelete=  this.handleItemDelete.bind(this);

        store.subscribe(this.handleStoreChange);
    }

    render(){
          return(
             <TodoListUI inputValue={this.state.inputValue} list={this.state.list} 
              handleInputChange = { this.handleInputChange} handleBtnClick =     
              {this.handleBtnClick} />
          )
      }
}

handleInputChange(e){
    const action = getInputChangeAction(e.target.value);
    store.dispatch(action);
}


UI组件

class TodoListUI extends Component {
    render () {
        const { inputValue,handleInputChange,handleBtnClick,list } = this.props;
        rerurn (
              <div>
                      <div>
                          <Input placeholder='todo info'  className='input' value=                  
                          {inputValue} onChange= {handleInputChange} ref={(input) => 
                          {this.input = input}}/>
                          <Button type='primary' onClick={handleBtnClick}>提交</Button>
                      </div>
                      <List
                          style={{marginTop:'10px',width:"300px"}}
                          bordered
                          dataSource={list}
                          renderItem={ item => (<List.Item>{item}</List.Item>) }
                      />
         </div>
        )
    }
}

傻瓜组件也可以改写成函数形式,加快性能


image.png

八、使用Redux-thunk中间件进行ajax请求

1.引入和配置


image.png

windows配置


image.png
2.ajax异步请求
image.png image.png

3.中间件的工作原理(作用在action和store之间)


image.png

4.扩展(redux-saga对大型项目而言更合适)


image.png
image.png

九、react-redux的使用

1.Provider


image.png

2.connect

import React, { Component } from 'react'
import store from './store';
import connect from 'react-redux';

class TodoList extends Component {
  render() {}
}

const mapStateToProps = (state) => { 
    return {
      inputValue:state.inputValue;
    }
 }
const mapDispatchToProps = (dispatch) => { 
  return { 
      changeInputValue(e){
        const action = {
          type:'change',
          value:e.target.value
        }
      }
  }
 }

export default connect(mapStateToProps,mapDispatchToProps)(TodoList)

十、样式

1.styled-components的使用(npm i styled-components)

全局样式


image.png

组件样式


image.png
image.png
写法
image.png
image.png
image.png
image.png
2.iconfont使用
image.png
image.png

十一、优化以及工具的使用

1.combineReducer的使用,便于组件中数据的管理


image.png

2.actionCreators和constants的拆分
3.immutable.js,阻止随意更改state


image.png
image.png
image.png
image.png
image.png
image.png

十二、路由(npm i react-router-dom)

1.App.js

import React, { Component } from 'react'
import store from './store';
import { Provider } from 'react-redux';
import Header from './common/header'
important Home from './pages/home'
import { BrowserRouter, Route } from 'react-router-dom'

class App extends Component{
  render() {
     return (
        <Provider store={store}>
            <div>
                <Header/>
                <BrowserRouter>
                    <Route path='/' exact render={ ()=><div>home</div>}></Route>
                    <Route path='/detail' exact component={Home}}></Route>
                     <Route path='/detail/:id' exact component={Home}}></Route>
                </BrowserRouter>
            <div>
       </Provider>
    )
  }
}

2.detail/index.js

1.获取路由参数

componentDidMount() {
  this.props.getDetail(this.props.match.params.id);
}

3.路由参数获取


image.png

4.路由跳转


image.png
image.png

十三、服务器

1、安装


image.png

2.使用


image.png

相关文章

网友评论

      本文标题:react(二)

      本文链接:https://www.haomeiwen.com/subject/dfnkvktx.html