创建项目
1.npx create-react-app myapp
2.cd myapp
3.npm start
文件说明
index.js文件:
//加快react运行速度的js文件
import * as serviceWorker from './serviceWorker';
补充:组件名称首字母必须大写
案例说明
数据基本绑定
import React, { Component } from 'react';
class Home extends Component {
constructor() {
super()
this.state={
user:{
username:"qiang",
age:30
}
}
}
render() {
return (
{this.state.user.username}
{this.state.user.age}
)
}
}
export default Home;
style和class的绑定
说明:
class=> className
for => htmlFor
import React,{Component} from 'react';
import '../assets/css/list.css';
class List extends Component{
constructor(){
super()
this.state={
name:["a","b","c"],
style:{
color:'red',
fontsize:'40px'
},
color:'red',
blue:'blue'
}
}
render(){
return(
- {this.state.name[0]}
// 注意此处:之所以两层{}是因为内部也是对象
- {this.state.name[1]}
- {this.state.name[2]}
- 字符串css
- 变量css
// 此处for的特殊写法
)
}
}
export default List;
图片引入和遍历
import React, { Component } from 'react';
import img from '../assets/image/a.png'
class New extends Component {
constructor() {
super()
this.state = {
arr:["a","b"],
//注意此处内部元素没有""包裹
arr1:[a
,b
]
}
}
render() {
//遍历方式一
let listResult=this.state.arr.map((val,index)=>{
return {val}--{index}
})
return (
引入图片方式一
引入图片方式二
{this.state.arr1}
{listResult}
//遍历方式二
{
this.state.arr.map((val,index)=>{
return {val}
})
}
);
}
}
export default New;
绑定this和传参
说明:jsx的点击事件是onClick,而且不能加(),这代表立即执行
import React, { Component } from 'react';
class New extends Component {
constructor() {
super()
this.state = {
msg: '元数据'
}
this.bindThis2 = this.bindThis2.bind(this)
}
test() {
console.log("成功");
}
bindThis1() {
console.log(this.state.msg);
}
bindThis2() {
console.log(this.state.msg);
}
bindThis3 = () => {
console.log(this.state.msg);
}
setStateInfo(info) {
this.setState({
msg: info
})
}
render() {
return (
{this.state.msg}
);
}
}
export default New;
事件对象案例(获取数据的两种方式)
import React, { Component } from 'react';
class New extends Component {
constructor() {
super()
this.state = {
msg: ''
}
}
test(event){
// console.log(event);事件对象
//获取自定义属性aid
let aid=event.target.getAttribute('aid');
console.log(aid);//123
}
inputChange=(event)=>{
//获取数据的方式一
// let value=event.target.value;
//获取数据的方式二
let value=this.refs.name.value;
this.setState({
msg:value
})
}
showInfo=()=>{
console.log(this.state.msg);
}
render() {
return (
);
}
}
export default New;
键盘事件
import React, { Component } from 'react';
class New extends Component {
constructor() {
super()
this.state = {
msg: ''
}
}
onKeyUpChange=(event)=>{
// console.log(event.keyCode);获取键盘事件码
//enter事件
if(event.keyCode==13){
let value=event.target.value;
this.setState({
msg:value
})
}
}
render() {
return (
{this.state.msg}
);
}
}
export default New;
实现双向数据绑定
import React, { Component } from 'react';
class New extends Component {
constructor() {
super()
this.state = {
msg: ''
}
}
inputChange=(e)=>{
this.setState({
msg:e.target.value
})
}
render() {
return (
{this.state.msg}
);
}
}
export default New;
说明:input绑定value时候必须加上onChange方法否则会报错,除非使用defaultValue
react中只有model改变影响view的单向数据流,所以如想实现双向数据绑定,必须手写
上面其实就是view改变改变model的过程代码
补充:
非约束型组件:例如非约束性组件中defaultValue就相当于原生dom的value,react不参与管理
约束型组件:例如非约束性组件中value,react参与管理(this.handleChange管理)
实际上,input中的value根本不是用户输入的值,而是onChange事件触发后,由于this.setState导致一次重新渲染,不过react会优化算法
表单相关
import React, { Component } from 'react';
class New extends Component {
constructor() {
super()
this.state = {
city:'',
citys:["北京","上海"],
sexs:[
{key:"乒乓球",value:false},
{key:"篮球",value:false},
{key:"足球",value:true}
]
}
}
submitMethod=(e)=>{
//阻止默认事件
e.preventDefault();
console.log(this.state);
}
optionSet=(e)=>{
this.setState({
city:e.target.value
})
}
sexsChange(index){
//react接管了默认点击操作,如果布变更数据,则界面点击无效
let sexs=this.state.sexs;
sexs[index].value=!sexs[index].value;
this.setState({
sexs
})
}
render() {
return (
{this.state.city}
);
}
}
export default New;
父子组件相关
父子组件互相传参
父组件:
import React, { Component } from 'react';
import Header from './Header'
class New extends Component {
constructor(props) {
super(props)
this.state = {
msg:"New传入的参数"
}
}
show=()=>{
console.log("被子组件调用的父组件的方法");
}
send2Parent=(info)=>{
this.setState({
msg:info
})
}
getChildCom=()=>{
//既然可以获取子组件,则属性方法自然都可以使用
console.log(this.refs.header);
}
render() {
return (
{this.state.msg}
);
}
}
export default New;
defaultProps和propTypes
defaultProps:父子组件传值中,如果父组件调用子组件的时候不给子组件传值,则可以在
子组件中使用defaultProps定义的默认值propTypes:验证父组件传值的类型合法性
子组件:
import React, { Component } from 'react';
//验证数据类型需要引入PropTypes
import PropTypes from 'prop-types';
class Header extends Component {
showParent=()=>{
console.log(this.props.new);
}
render() {
return (
{this.props.msg}
);
}
}
//如果例如父组件没传入title则使用该默认值,否则使用父组件传值
//针对的是this.props.title是否传入
Header.defaultProps={
title:"标题"
}
//验证数据类型,注意propTypes和PropTypes
Header.propTypes={
title:PropTypes.string
}
export default Header;
生命周期
1.组件加载的时候触发的函数:
constructor(构造函数) componentWillMount(组件将要挂载) render(渲染) componentDidMount(组件挂载完毕)
2.组件更新的时候触发的函数:
shouldComponentUpdate(更新数据) ComponentWillUpdate(组件将要更新) render componentDidMount
2.1 补充
shouldComponentUpdate(nextProps,nextState){
比较props或者states,返回true则更新照常,返回false则取消更新,
且不会调用下面的两个生命周期函数
}
分别是更新后的父子组件的传递参数和更新后的state
使用场景:父组件有子组件A和子组件B,当父组件调用this.setState更新一个作为子组件A属性
的state时,render方法被再次调用,此时组件A和组件B同时被更新,其实真正改变的只有组件
A,但组件B也同时被要求更新了,这是没有必要的,于是shouldComponentUpdate就显的有用
了,在该函数体内比较props或是states,如果没有改变就取消这个更新,这对性能上算是一个提
升。因为传递过来到组件的都是更新过的,可以和该组件当前的prop和state比较,从而通过返回布尔值确定是否需要更新该组件
3.在父组件里面改变props传值的时候触发的函数:
componentWillReceiveProps
4.组件销毁的时候触发的函数:
componentWillUnmount
注意:绝对不要在componentWillUpdate和componentDidUpdate中调用this.setState方法,否则将导致无限循环调用。
组件销毁的案例:
父组件:
import React, { Component } from 'react';
import Header from './Header'
class New extends Component {
constructor(props) {
super(props)
this.state = {
msg:"参数",
flag:true
}
}
destoryChild=()=>{
this.setState({
flag:!this.state.flag
})
}
render() {
return (
{
this.state.flag? :''
}
);
}
}
export default New;
子组件:
import React, { Component } from 'react';
class Header extends Component {
render() {
return (
Header组件
);
}
componentWillUnmount(){
console.log("组件销毁");
}
}
export default Header;
说明:每一次点击切换子组件都可以让子组件显示或者销毁,每次销毁时候触发子组件的componentWillUnmount