React学习记录(1)

React学习记录

React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。

React 特点

1.声明式设计 −React采用声明范式,可以轻松描述应用。
2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
3.灵活 −React可以与已知的库或框架很好地配合。
4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

React 项目创建

$ create-react-app my-app
$ npm start

项目目录结构

my-app/
  README.md
  node_modules/
  package.json
  .gitignore
  public/
    favicon.ico
    index.html
    manifest.json
  src/
    App.css
    App.js
    App.test.js
    index.css
    index.js
    logo.svg

my-app下
public为网页主界面和相关资源:
1.index.html为整个项目的根,可改变项目title等
2.manifest.json配置应用的图标,名称等信息
其他为配置需要的资源
src为主要的项目编写目
1.App.js与App.css 一般作为主组件,通过这个组件定义项目布局等
2.index.js与index.css 通过ReactDOM.render vdom渲染至真实dom树的过程,一般只调用App.js组件
3.可在目录下创建component目录进行组件编写

React 渲染

通过ReactDOM.render vdom渲染至真实dom树

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

React JSX

不一定要使用JSX,但是使用起来会很方便

JSX, 一种 JavaScript 的语法扩展。可以简单的认为HTML与js 的合并(一些Html标识符如class被替代为className)

1.在JSX中写js代码,需写在{}中
2.不能使用ifelse 可用三元运算符替代
3.样式文件通过import导入

实例Header.jsx

import React, { Component , Fragment} from "react";
import './Header.less'

class Header  extends Component{

    constructor(props) {
        super(props);
        this.state = {
            value :''     
        }
    }

    render(){
        return (
            <div className="header">
                <span>ToDoList</span>
                <form>
                    <input 
                    type="text" 
                    placeholder="添加ToDo" 
                    value={this.state.value}  
                    onChange={this.handleInputChange.bind(this)}
                    onKeyPress={this.keyPress.bind(this)}/>
                </form>
            </div>
        )
    }
    handleInputChange(e) {
        this.setState({
            value : e.target.value
        })
    }
    keyPress(e){
        if (e.which !== 13) return
        this.props.sonMess(this.state.value);
        this.setState({
            value : ''
        })
        e.preventDefault();
    }
}

export default Header;

React 组件

两种方式来创建组件
1.通过函数创建

function HelloMessage(props) {
    return <h1>Hello World!</h1>;
}

2.通过Es6 创建

扫描二维码关注公众号,回复: 11430318 查看本文章
class Welcome extends React.Component {
  render() {
    return <h1>Hello World!</h1>;
  }
}

需导入import React, { Component , Fragment} from “react”;
最后将组件export default State出来 ,这样别的组件可以调用

传值方式
父传子:使用 this.props 对象

function HelloMessage(props) {
    return <h1>Hello {props.name}!</h1>;
}

<HelloMessage name="Runoob"/>;

子串父:使用this.props对象 但是只能通过函数,函数传参数

class Task  extends Component{
	render(){
        return (
        	<input type="checkbox" onChange={this.stateChange.bind(this)}/>
        )
    }
    stateChange(e){
        this.props.sonMess(msg);
    }
}
<Task sonMess={this.getSonMess.bind(this)} />
getSonMess(item){
        alert(item) //子组件传来的msg
}

默认 Props

HelloMessage.defaultProps = {
  name: 'Runoob'
};

props验证

MyTitle.propTypes = {
  title: PropTypes.string
};

实例

子组件Task.js

import React, { Component , Fragment} from "react";

import "./Task.less";

class Task  extends Component{

    constructor(props) {
        super(props);
        this.state = {
            id : this.props.taskIndex
        }
    }

    render(){
        return (
            <div className="task">
                <div></div>
                <input type="checkbox" checked={this.props.checked} onChange={this.stateChange.bind(this)}/>
                <span>{this.props.value}</span>
                <div onClick={this.taskDelete.bind(this)}>-</div>
            </div>
        )
    }
    stateChange(e){
        this.props.sonMess({'value' : this.props.value , 'checked' : e.target.checked,'id':this.state.id});
    }
    taskDelete(e){
        this.props.sonDeleteMess({'value' : this.props.value , 'checked' : this.props.checked,'id':this.state.id});
    }
}

export default Task

父组件

import React, { Component , Fragment} from "react";

import './State.less'
import Task from "../Task/Task";

class State  extends Component {

    constructor(props) {
        super(props);
        this.state = {
        }
    }

    render() {
        return (
            <div className="state">
                <div className="Run">
                    <div className="run-top">
                        <span>正在进行</span>
                        <span>{this.props.listRun.length}</span>
                    </div>
                    <div className="run-task">
                        {
                            this.props.listRun.map((item , index) => {
                            return <Task 
                            checked={false} 
                            key={index} 
                            value={item.value}
                            taskIndex = {item.id}
                            sonMess={this.getSonMess.bind(this)} 
                            sonDeleteMess={this.getSonDeleteMess.bind(this)}/>
                            })
                        }
                    </div>
                </div>
                <div className="Run">
                    <div className="run-top">
                        <span>已经完成</span>
                        <span>{this.props.listSuccess.length}</span>
                    </div>
                    <div className="run-task">
                        {
                            this.props.listSuccess.map((item , index) => {
                            return <Task 
                            checked={true} 
                            key={index} 
                            value={item.value} 
                            taskIndex = {item.id}
                            sonMess={this.getSonMess.bind(this)}
                            sonDeleteMess={this.getSonDeleteMess.bind(this)} />
                            })
                        }
                    </div>
                </div>
            </div>
        )
    }
    getSonMess(item){
        this.props.sonStateMess(item)
    }
    getSonDeleteMess(item){
        this.props.sonTaskDelete(item)
    }

}

export default State

React 状态State

State通过与用户交互,实现不同状态(不同的数据),然后进行渲染,使页面与用户数据一致
父组件或子组件都不能知道某个组件是有状态还是无状态,也就是说本组件以外,其他组件不能访问其状态

数据自顶向下流动:也称作单向数据流,状态由组件特有,只能影响该组件树下方的组件(通过父传子),并且同一个组件创建的不同实例也相互不影响,独立存在

与props的区别
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。

state与props的结合使用
在父组件中使用state与用户交互,通过props传给子组件

React 事件处理

1.驼峰式写法 如onClick
2.传入函数作为事件处理
3.事件处理函数中带e参数,e为响应节点,可通过e.target访问value等
4.必须使用preventDefault 对默认事件进行阻止动作

重点:
调用事件处理函数需要通过bind绑定this本组件,要不然访问不了本组件的数据

实例

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
 
    // 这边绑定是必要的,这样 `this` 才能在回调函数中使用
    this.handleClick = this.handleClick.bind(this);
  }
 
  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }
 
  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

React 列表

一般通过map
重点:需要给key值
key可以方便react识别那些元素发生了变化,最好是列表中唯一的标识,一般以index赋值

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((numbers) =>
  <li key={number.toString()}>{numbers}</li>
);

React 组件API

1.设置状态:setState
在组件内,不能直接通过this.state与= 改变状态,那样不会触发React渲染,需要调用setState 改变状态
setState()总是会触发一次组件重绘
setState 是异步的
如果一个操作必须要在一个 setState 之后进行的话。可以使用回调函数

this.setState({
            listRun : list
        })

2.替换状态:replaceState 不常用
3.设置属性:setProps 不常用
4.替换属性:replaceProps 不常用
5.强制更新:forceUpdate
默认情况下,当你的组件的 state 或者 props 改变,你的组件将会重绘
如果数据隐式改变,可以用调用 forceUpdate() 来告诉 React 它需要重新运行 render()。
6.获取DOM节点:findDOMNode
如果这个组件已经被挂载到了 DOM,它返回相应的浏览器原生的 DOM 元素
7.判断组件挂载状态:isMounted 不常用

React 组件生命周期

React组件生命周期
三个状态
1.Mounting:已插入真实 DOM
2.Updating:正在被重新渲染
3.Unmounting:已移出真实 DOM

生命周期(周期函数)分为两类:挂载卸载过程和更新过程
1. 挂载卸载过程
1.1.constructor()
constructor()中完成了React数据的初始化,它接受两个参数:props和context,
1.2.componentWillMount()
在渲染前调用,在客户端也在服务端。
1.3.componentDidMount()
在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
1.4.componentWillUnmount ()
在组件从 DOM 中移除之前立刻被调用。

2. 更新过程
2.1. componentWillReceiveProps (nextProps)
在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
2.2.shouldComponentUpdate(nextProps,nextState)
返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
可以在你确认不需要更新组件时使用。
2.3.componentWillUpdate (nextProps,nextState)
在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
2.4.componentDidUpdate(prevProps,prevState)
在组件完成更新后立即调用。在初始化时不会被调用。
2.5.render()

React 后端数据获取

React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据时可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。

componentDidMount() {
    this.serverRequest = $.get(this.props.source, function (result) {
      var lastGist = result[0];
      this.setState({
        username: lastGist.owner.login,
        lastGistUrl: lastGist.html_url
      });
    }.bind(this));
  }

React React 表单与事件

在React中,如果将表单绑定在state上,只能通过setState方法更新。
所以需要事件onChange来监听input的变化,并修改state

<form>
      <input 
      type="text" 
      placeholder="添加ToDo" 
      value={this.state.value}  
      onChange={this.handleInputChange.bind(this)}
      onKeyPress={this.keyPress.bind(this)}/>
</form>

handleInputChange(e) {
        this.setState({
            value : e.target.value
        })
 }

React ref

1.ReactDOM.render()渲染组件时返回的是组件实例(只能是class声明的组件);
2.渲染dom元素时,返回是具体的dom节点。

ref属性可以设置为一个回调函数
ref 属性接受一个回调函数,它在组件被加载或卸载时会立即执行。

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.focus = this.focus.bind(this);
  }

  focus() {
    // 直接使用原生 API 使 text 输入框获得焦点
    this.textInput.focus();
  }

  render() {
    // 使用 `ref` 的回调将 text 输入框的 DOM 节点存储到 React
    // 实例上(比如 this.textInput)
    return (
      <div>
        <input
          type="text"
          ref={ (input)=>{this.textInput=input}}/>
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focus}
        />
      </div>
    );
  }
}

React 一些细节

1.取值函数(getter)和存值函数(setter)
您可以添加以get或set为前缀的方法来创建getter和setter,它们是根据您正在执行的操作执行的两个不同的代码:访问变量或修改其值。
对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

get buttons() {
    return ['add', 'delete'];
  }
//获得返回的数组

2.在dva中使用dva-router的routerRedux来跳转路由,并传值过去

goToDetailPage = record => {
    const { dispatch } = this.props;
    const pathname = `/module-user/user/detail/${record.data.employeeNumber}`;
    dispatch(
      routerRedux.push({
        pathname,
      })
    );
  };

猜你喜欢

转载自blog.csdn.net/weixin_44749729/article/details/107359870