遍历列表,遍历对象,以及组件
1.遍历列表(map和forEach的区别)
return后面不能为空格,回车,否则就是报错,如果非要换行,,在return后面加一个小括号,变成了一个表达式(自执行函数)
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.js"></script>
</head>
<body>
<div id="box">
</div>
<script type="text/babel">
var arr = ['aaa', 'bbb', 'cccc']
var lesson = ['json', 'pp', 'll']
var curIndex = 0
function showList(arr) {
return (
<ul>
{
arr.map((item, index) => {
return <li key={index}
style={{color:index===curIndex?"red":''}}
onClick={() => {
curIndex = index,
render()
}
}
>
{item}
</li>
})
}
</ul>
)
}
function a2(arr){
var tem = []
for(var i=0;i<arr.length;i++){
tem.push(<li key={i}>{arr[i]}</li>)
}
return <ul>{tem}</ul>
}
function render() {
ReactDOM.render(
<div>
{showList(arr)}
{a2(lesson)}
</div>,
document.getElementById('box')
)
}
render()
</script>
forEach和map的区别
**1、map:对每一项数据进行映射,不改变本身的数组,返回布尔值
例如:
var arr=[1,2,3]
var newArr=arr.map((item)=>{
return item*2
})
console.log(newArr)//不改变原数组
**2、forEach:遍历所有成员,且改变数组的本身
例如
var arr =[1,2,3]
arr.forEach((item,index,arr)=>{
arr[index] = item+1
})
console.log(arr)
二.组件(无状态组件,类组件)
1.无状态组件
const 组件的名字 =(props)=>{
return jsx表达式
}
无状态组件设置默认值
2.类组件
首先里面有三个属性(state,props,refs),简单理解知道一下,接下来会有代码示例
state:表示组件内部的数据
props:外部的数据
refs:标识一个组件节点
class 组件的名字 extends React.Component{
constructor(props){
super(props) 必须存在super,否则你无法在构造函数中使用 this
//构造函数//
}
render(){}
}
三、组件设置默认值(父子组件向子组件没传值的情况下,在子组件中设置默认值)
一、类组件
static defaultProps={
n:5
}
例如:
//子组件
import React, { Component } from 'react'
export default class One extends Component {
constructor(props){
super(props)
console.log(this.props.a,this.props.n)
}
static defaultProps={
n:'sun'
}
render() {
return (
<div>
11
</div>
)
}
}
//父组件:
import React from 'react';
components/Count"
import One from "./components/One"
import './App.css';
export default class App extends React.Component {
constructor(props){
super(props)
this.state={
name:'chen',
age:11
}
}
render() {
let {name,age} = this.state
return (
<div className="App">
<One a={age}/>
</div>
)
}
}
2、无状态组件:
组件名.default={
key:默认值
}
组件设置默认值的属性
1、类组件
引入 {propTypes} from "propTypes"
static Proptypes={
a:propTypes.number
}
2、无状态组件
组件名.proptypes={
a:protypes.类型.isRequired(必须传,不穿报警告)
}
扩展:super浅析:
1.有时候我们不传 props,只执行 super(),或者没有设置 constructor 的情况下,依然可以在组件内使用 this.props,为什么呢?
其实 React 在组件实例化的时候,马上又给实例设置了一遍 props:
2.那是否意味着我们可以只写 super() 而不用 super(props) 呢?
不是的。虽然 React 会在组件实例化的时候设置一遍 props,但在 super 调用一直到构造函数结束之前,this.props 依然是未定义的。
如果这时在构造函数中调用了函数,函数中有 this.props.xxx 这种写法,直接就报错了。而用 super(props),则不会报错。
3.遍历对象
【此处遍历对象使用父子传值的方式】
[Object.keys:拿到key值]
[Object.values:拿到values值]
[Object.entries:拿到键值对组成的数组]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.js"></script>
</head>
<body>
<div id="box">
</div>
<script type="text/babel">
var obj = { a: '1', b: 'bbb', c: 'cccc' }
const App = ((props) => {
console.log(props.obj2)//拿到父组件传过来的值
//{a: "1", b: "bbb", c: "cccc"}
return <div>
{
//对象遍历使用的是Object.keys,将对象转为数组类型,,在遍历,拿到key值
Object.keys(props.obj2).map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</div>
})
function render() {
ReactDOM.render(
<div>
<App obj2={obj}/>//将值传给子组件
</div>,
document.getElementById('box')
)
}
render()
</script>
</body>
</html>
扩展:对象浅拷贝(2种方式)
1.首先,了解一下什么是浅拷贝和深拷贝?
1.假设B复制了A,修改A的时候,看B是否发生变化:
2.如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
3.如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)
4.浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,
5.深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存,
6.使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。
对象浅拷贝的第一种方式
1.使用解构赋值:var obj ={a:'1',b:'2'}
let a = {
age: 1
}
let b = {...a}
a.age = 2
console.log(b.age) // 1
2.首先可以通过 Object.assign 来解决这个问题。
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
类组件中的ref参数(标识节点)
第一种: class App extends React.Component {
add() {
console.log(this.refs.submit)
}
render() {
return (
<div>
<input ref='submit' type="button" onClick={this.add.bind(this)} />
</div>
)
}
}
第二种:在需要操作的dom节点里绑定回掉函数,在componentDidMount中拿到值
console.log(this.textInput)
class App extends React.Component {
componentDidMount() {
console.log(this.textInput)
}
render() {
return (
<div>
<input type="text" ref={input => this.textInput = input} />
</div>
)
}
}
ReactDOM.render(<App />,
document.querySelector("#box"))
第三种标识节点:
1、引入内置的createRef
2、实例代码
import React, { Component } from 'react'
import {createRef} from 'react'
export default class index extends Component {
constructor(props){
super(props)
this.state={
n:createRef()
}
}
componentDidMount() {
console.log(this.state.n)
}
render() {
return (
<div>
<node ref={this.state.n} />
</div>
)
}
}