ajax mysql项目 react_React项目详解

React项目指导

使用webpack需要安装的依赖

webpack,webpack-cli,react,react-dom

babel-loader,@babel/core,@babel/preset-env,@babel/preset-react

设置.babelrc,{"presets": ["@babel/preset-env","@babel/preset-react"]}

设置scripts:

"dev": "webpack --mode development",

"build": "webpack --mode production"

设置webpack-dev-server:

devServer: {

compress: true,

port: 9000,

hot: true

},

"start": "webpack-dev-server --config webpack.config.js"

设置performance:

performance: {

hints: false

}

Component

基本组件

let title =

Hello, world!

ReactDOM.render(title,document.getElementById('root'))

动态组件

import React from 'react';

import ReactDOM from 'react-dom';

let displayTime = () => {

let nowTime = (

现在时间:{new Date().toLocaleTimeString()}

);

ReactDOM.render(t

nowTime,

document.getElementById('root')

);

};

setInterval(displayTime, 1000);

class组件构建器

import React, {Component} from 'react';

import ReactDOM from 'react-dom';

class HelloTitle extends Component {

render() {

return

Hello,World!

}

}

ReactDOM.render(

,

document.getElementById('root')

);

props属性

import React, {Component} from 'react';

import ReactDOM from 'react-dom';

class HelloTitle extends Component {

render() {

return

Hello,{this.props.name}!

}

}

let titleDiv = (

);

ReactDOM.render(

titleDiv,

document.getElementById('root')

);

props多层使用

import React, {Component} from 'react';

import ReactDOM from 'react-dom';

class HelloTitle extends Component {

render() {

return

Hello,{this.props.name}!

}

}

class HelloDiv extends Component {

render() {

return

}

}

ReactDOM.render(

,

document.getElementById('root')

);

组件复用

import React, {Component} from 'react';

import ReactDOM from 'react-dom';

class HelloTitle extends Component {

render() {

return

{this.props.content}

}

}

class HelloDiv extends Component {

render() {

return

}

}

ReactDOM.render(

,

document.getElementById('root')

);

Component的状态state和生命周期

state属性

constructor(props) {

super(props);

this.state = {

time: new Date().toLocaleTimeString()

}

}

render() {

return

现在时间是{this.state.time}

}

组件构建完成后先执行的动作,componentDidMount():

componentDidMount() {

let upTime = () => {

this.setState({time: new Date().toLocaleTimeString()})

};

setInterval(upTime, 1000)

}

setState()修改状态值

this.setState({time: new Date().toLocaleTimeString()})

生命周期

在constructor中初始化组件内部的资料。

使用render()在网页上输出组件内容。

输出后会执行componentDidMount()进行一次调用。

当组件内部的state值被修改时执行componentDidUpdate()。

当组件被移除时会执行componentWillUnmount()的内容一次。

componentDidMount()

Component已经render到实体DOM阶段完成的时候触发;

此method只会被呼叫一次;

在这裡可以setState(),并会再次重新render、component一次;

可以放入具有side effect的function,如setInterval、呼叫API等等。

componentWillUnmount()

Component即将从实体DOM阶段移除「之前」的时候触发;

也是只会被呼叫一次;

不可以在这裡使用setState();

也可以放入具有side effect的function。

class Clock extends Component {

constructor(props) {

super(props);

this.state = {

currentTime: new Date().toLocaleString()

}

}

componentDidMount() {

this.timer = setInterval(this.updateTime, 1000)

}

componentWillUnmount() {

clearInterval(this.timer)

}

updateTime = () => {

this.setState({

currentTime: new Date().toLocaleString()

})

};

render() {

const {currentTime} = this.state;

return (

{currentTime}

)

}

}

component各阶段的生命周期方法

挂载(Mounting):组件一开始呈现到真实网页的过程

class LifeCycle extends Component {

constructor(props) {

super(props);

// 建构式,推进组件初始state设定,绑定方法,接受父级props的地方

// 只会被调用一次

// 不适合使用具有side effect的工作,如AJAX调用

}

static getDerivedStateFromProps(nextProps, prevState) {

// React V16.3新增的生命周期方法

// 在组件建构之后,render()被调用之前

// 每次接收新的props后回传object更新state;也可以回传null不做更新

}

UNSAFE_componentWillMount() {

// 即将在React V17中移除,不可与static getDerivedStateFromProps同时出现

// 在render()调用之后被调用,且之后被调用一次

// 会用到的地方仅在于服务器端的应用

// 适合设定初始化数据的地方,不适合做有side effect的工作

}

render() {

// 在class component中「唯一」必要存在的方法

// 尽量pure,不应该改变component的state

// 如需要和browser有互动的话,将其放进componentDidMount()中

return (

)

}

componentDidMount() {

// 在render()被调用后,组件已经在真实DOM呈现之后被调用执行

// 只会被调用一次,适合执行AJAX、计时器设定、加入eventListener等有副作用的工作

// 调用setState()可能会再执行一次render()

}

}

更新(Updating):使用者的操作中,组件的状态和属性被改变

class LifeCycle extends Component {

UNSAFE_componentWillReceiveProps(nextProps) {

// 即将在React V17中移除,不可与static getDerivedStateFromProps同时出现

}

static getDerivedStateFromProps(nextProps, prevState) {

// React V16.3新增的新生命周期方法

// 在组件构建之后,render()被调用之前

// 每次接收新的props后回传object更新state;也可回传null不做更新

// 搭配componentDidUpdate,可以达到与componentWillReceivedProps的效果

}

shouldComponentUpdate() {

// 让使用者自定义是否进行component更新,预设都会默认更新

// 只有少部分的情况才会使用此方法,如进行复杂耗时的计算

// 尽量不要检查太过深层的值,也不适合执行具有side effect的工作

}

UNSAFE_componentWillUpdate(nextProps, nextState) {

// 即将在React V17中移除,不可与static getDerivedStateFromProps同时出现

// 在组件即将更新「之前」调用

// 不能在此使用setState方法,若要改变请用getDerivedStateFromProps

}

getSnapshotBeforeUpdate(prevProps, prevState) {

// 在render之后,在最新的渲染前输出交给真实DOM前会立即执行

// 返回的值作为componentDidUpdate的第三个值

// 搭配componentDidUpdate,可以达到与componentWillUpdate的效果

}

componentDidUpdate(prevProps, prevState, snapshot) {

// 会发生在更新「之后」被调用

// 如果shouldComponentUpdate回传的是false,就不会调用此方法

// 适合执行具有side effect的地方

}

}

卸载(Unmounting):组件要移除真实DOM的阶段

class LifeCycle extends Component {

componentWillMount() {

// 在组件即将要移除真实DOM时会执行

// 可以在这里做中断网络连接、清楚计时器、移除事件监听器

// 不适合使用setState方法

}

}

catch error

class ErrorBoundary extends Component {

constructor(props) {

super(props);

this.state = {

hasError: false

}

}

componentDidCatch(error, info) {

// 是error handle的方法,与挂载和更新阶段有密切关系

// 可以用来捕捉子组件的任何JavaScript的错误

// 可以记录这些错误,或是呈现在目前反馈用的操作界面上

// 不能在事件的callback上使用

// 显示在反馈的UI上

this.setState({hasError: true});

// 也可以用额外的错误记录服务

logErrorMyService(error, info);

}

render() {

if (this.state.hasError) {

return

Something went wrong...

}

return this.props.children

}

}

上面就是component可以使用的生命周期方法,最常用主要是这些:

constructor()

render()

componentDidMount()

compoinentDidUpdate()

componentWillUnmount()

Component的事件处理

取得触发事件的DOM

class InputGender extends Component {

constructor(props) {

super(props);

this.state = {

gender: ''

};

this.changeGender = this.changeGender.bind(this)

}

changeGender(event) {

console.log(event.target.value);

this.setState({

gender: event.target.value

});

}

componentDidUpdate() {

console.log(`已将state.gender变动为:${this.state.gender}`)

}

render() {

return (

)

}

}

class HelloTitle extends Component {

render() {

return

{this.props.title}

}

}

{(this.state.gender === 'M') ? : }

用绑定的state取得输入资料

class EasyForm extends Component {

constructor(props) {

super(props);

this.state = {

name: ""

};

this.changeState = this.changeState.bind(this);

this.submitForm = this.submitForm.bind(this);

}

changeState(event) {

this.setState({

name: event.target.value,

});

}

submitForm(event) {

let element = document.querySelector('span');

element.innerHTML = `${this.state.name}`;

event.preventDefault()

}

render() {

return (

姓名:

现在输入的名字是:

)

}

}

受控组件

class EasyForm extends Component {

constructor(props) {

super(props);

this.state = {

lists: [

{id: '01', listName: '写文章', check: false},

{id: '02', listName: '写代码', check: false},

{id: '03', listName: '旅游', check: true},

{id: '04', listName: '踢球', check: true},

{id: '05', listName: '公益', check: false},

]

};

this.submitForm = this.submitForm.bind(this);

this.changeState = this.changeState.bind(this);

}

changeState(index) {

let arrLists = this.state.lists;

arrLists[index].check ? arrLists[index].check = false : arrLists[index].check = true;

this.setState({

lists: arrLists,

});

}

submitForm(event) {

let status = "目前做了:";

this.state.lists.map((list) => list.check ? status += `${list.listName} ` : '');

console.log(status);

event.preventDefault()

}

render() {

let lists = this.state.lists.map((list, index) => (

checked={list.check}

onChange={this.changeState.bind(this, index)}

key={list.id}

/>

{list.listName}

));

return (

每日待办清单:

{lists}

)

}

}

非受控组件

class EasyForm extends Component {

constructor(props) {

super(props);

this.submitForm = this.submitForm.bind(this);

this.filebox = React.createRef()

}

submitForm(event) {

console.log(`选择文档为:${this.filebox.current.files[0].name}`)

event.preventDefault()

}

render() {

return (

上传文档:

)

}

}

refs操作DOM

class App extends Component {

constructor() {

super();

this.state = {

itemList: []

};

this.addFile = React.createRef();

}

addItem = () => {

const {itemList} = this.state;

const tempList = Object.assign([], itemList);

if (this.addFile.current.value !== '') {

tempList.push(this.addFile.current.value);

}

this.setState({

itemList: tempList

});

this.addFile.current.value = ''

};

render() {

const {itemList} = this.state;

return (

{itemList.map((item, index) =>

{item}

)}

);

}

}

实例:TODOLIST

TodoList.js

class TodoList extends Component {

constructor(props) {

super(props);

this.state = {

list: []

}

}

addItem = (text) => {

const {list} = this.state;

if (text !== '') {

const tempArr = list.concat({

id: list.length + 1,

text,

status: false

});

this.setState({list: tempArr})

}

};

toggleStatus = (id) => {

const {list} = this.state;

const tempArr = list.map(item => {

if (item.id.toString() === id.toString()) {

return ({

id: item.id,

text: item.text,

status: !item.status

})

}

return item;

});

this.setState({list: tempArr})

};

render() {

const {list} = this.state;

const divStyle = {

width: '250px',

margin: 'auto',

textAlign: 'left'

};

return (

{list.map(item => (

key={item.id}

id={item.id}

status={item.status}

onItemClick={this.toggleStatus}

>

{item.text}

))}

)

}

}

TodoForm.js

class TodoForm extends Component {

constructor(props) {

super(props);

this.inputRef = React.createRef();

}

formSubmit = (e) => {

const {onAddItem} = this.props;

e.preventDefault();

onAddItem(this.inputRef.current.value);

this.inputRef.current.value = ''

};

render() {

return (

submit

)

}

}

TodoItem.js

class TodoItem extends Component {

handleItemClick = (e) => {

const {onItemClick} = this.props;

onItemClick(e.target.id)

};

render() {

const {children, id, status} = this.props;

return (

id={id}

onClick={this.handleItemClick}

data-status={status}

style={

status ?

{textDecoration: 'line-through'} :

{textDecoration: 'none'}

}

>

{children}

)

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值