React 学习笔记

JSX

2019.10.08

const 声明一个变量
const 变量名 = (内容);

内容可以是
"字符串"
<标签名>标签内容{表达式}

表达式可以是任何 js 表达式,(for 循环不行,不知道为啥)

JSX 本身也是一个表达式
语法上更接近 js 而不是 html,所以使用驼峰命名

JSX 元素渲染
React 元素

使用 ReactDOM.render();来渲染根节点,并传入 你想渲染的React元素
语法:
ReactDOM.render(元素名, document.getElementById('root'));

更新 UI 的唯一方式是创建一个全新的元素并将其传入 ReactDOM.render();

在实践中,大多数 React 应用只会调用一次ReactDOM.render();
通过 setState() 方法可以刷新界面

JSX组件
使用 JS 函数来自定义组件:
function 组件名(形参){
return <标签名>标签内容{形参.属性名};
}

调用自定义的组件:
const 变量名 = <函数名 属性名=属性值 />

当 React 元素为自定义组件时,它会将 JSX 所接收的属性转换成一个单个对象传递给组件,这个对象被称之为"props",访问属性参数时使用:props.属性名
组件参数也可以直接传一个 model

组件名称必须以大写字母开头

组件也可以写成class 组件,写法如下:
class 组件名 extends Component {
render() {
return (


{this.props.参数名.属性名}

);
}
}
*为了严谨起见,我会将所有的组件均采用以上定义为 class 的写法

组件可以理解为 app 开发中的自定义 view,其本质可以看做是类

props 属性
props 属性是组件中自带的属性之一,其可以理解为该组件接收到的参数的一个集合.在使用 class 方式声明组件时不需要写出该属性,在给组件赋值时,所有的参数都作为 props 的一个属性获取.
*可以理解为隐形的参数集合

State 属性
State 是组件中自带的属性之一,当组件中的元素被指定为 State 的值后,State 的值改变,该元素会相应进行刷新(相当于数据绑定).
只有使用class 方式声明的组件才能调用 state属性,调用方式:
<标签名>this.state.属性名
在给 state 属性赋值时标签内容会自动改变,赋值方式:
this.setState({属性名: 属性值});
*使用 "=" 等于号的方式赋值是无效的,组件不会被重新渲染(不知道数据会不会变)
构造函数是唯一可以给 this.state 赋值的地方
state 的变量可以单独被更新

组件的生命周期函数:
1构造函数:
constructor(props) {
super(props);
//代码...
};
}
2渲染
render(){
//代码
}
3组件已经被挂载
componentDidMount() {
//代码
}
4组件即将被卸载
componentWillUnmount() {
//代码
}

组件的state数据是向下流动的
相当于父视图的 state可以传递给子视图,子视图无法传递数据给父视图

箭头函数: 适合用作匿名函数
function 函数名 (参数1,参数 2) {函数声明}
等同于
(参数1,参数 2) => {函数声明}

单一表达式可以省略 return 和 {}
单一参数可以省略()

2019.10.09
事件处理
React 的事件命名采用小驼峰式而不是纯小写
使用JSX语法时需要传入一个函数作为事件处理函数而不是一个字符串
语法:
<控件名 事件名={事件处理函数名}>控件内容

如要阻止默认行为,需要在事件中调用
props.preventDefault();
方法

在定义组件时,通常将事件处理函数声明为 class 中的方法,此时需要在constructor方法中进行 this 绑定,语法如下:
// 为了在回调中使用 this,这个绑定是必不可少的
this.事件函数名 = this.事件函数名.bind(this);
*在 class 内部声明函数时不需要加 function 前缀
*在 class 内部不需要声明属性,直接用 State 就行

向事件函数传递参数,语法如下:
<标签名 事件名={this.事件函数名.bind(this, 参数)}>标签内容
例如:

取出参数的语法如下:
handleClick(props){
//这里写了一个阻止默认事件的方法
props.preventDefault();
}

条件渲染
即通过 if 语句,三目运算符或 && 与运算符进行元素的渲染
if 语句没什么难的,语法如下:
render() {
let 变量名;
if(条件){
//条件成立
变量名=<标签 1>
}else{
//条件不成立
变量名=<标签 2>
}
return (


{变量名}

);
}

与运算符语法如下,比较新颖:


{条件语句 &&
<标签名>
标签内容

}

*之所以能这样做,是因为在 JavaScript 中,true && expression总是会返回 expression, 而 false && expression 总是会返回 false。因此,如果条件是 true&& 右侧的元素就会被渲染,如果是 false,React 会忽略并跳过它。

三目运算符语法如下:
{条件语句 ? (<标签>) : (<标签>)}

可以通过让 render() 方法直接 return null; 的方式来阻止组件的渲染.
*在组件的 render 方法中返回 null 并不会影响组件的生命周期。componentDidUpdate 依然会被调用。

列表
map()函数,相当于 forin 循环,写法如下:
数组.map((item) => (<标签>{item}));

数组.map(function(item) {return (<标签>{item})})
其返回值是一个新的数组,可以定义变量来接收它

key
列表需要一个 key用来帮助 React 识别哪些元素改变了,因此需要给 map()方法里的元素附一个 key 值,,通常使用元素的 id 来作为 key,当数组的顺序不变时,当不显式赋值时,React 会默认使用 index 给 key 赋值.赋值方法如下:
const todoItems = 数组.map((item) =>


  • {item.text}

  • );
    *所有在 map()方法中创建的元素都需要设置 key 属性,其子元素不需要
    同一个 map()方法中创建的元素的 key 应当是独一无二的,不同 map 方法中的元素的 key 可以是相同的
    key 属性是无法被读取的,如需访问其值,需要设置其他的属性名

    表单
    受控组件
    在 HTML 中,表单组件是自带状态的,而在 React 中使用受控组件,即将表单元素的状态"value"储存至组件的 State 中,同时在渲染时其状态也从 State 中获取,这样就可以在表单元素的 value 改变时动态获取到其 value.
    代码如下:
    class 组件名 extends React.Component {
    constructor(props) {
    super(props);
    this.state = {value: ''};

    this.回调函数 = this.回调函数.bind(this);
    

    }

    回调函数(event) {
    this.setState({value: event.target.value});
    }

    render() {
    return (




    );
    }
    }

    *其思想在于动态改变 state 和根据 state 动态刷新表单组件.
    *可以将数组传入 value 属性中


    是一个非受控组件,因为其 value 只读

    当组件中有多个受控元素时,可以给每个元素添加 name 属性,并通过判断 name 属性的值来进行相应的操作.
    给 state 赋值时的语法:
    this.setState({
    [name]: value
    });

    *setState 方法可以自动合并属性,所以调用其可以更改部分属性.其方式类似于OC中的字典写值操作(可以将 state 当做一个字典)

    当受控组件的 value 设置为{null}时其值可被更改,如下:
    ReactDOM.render(, mountNode);//不可更改
    ReactDOM.render(, mountNode);//可更改

    状态提升
    由于 React 组件这个东西没有类似于iOS开发的公开属性和私有属性的概念,也没有代理和回调,所以当其子控件向父控件传值时,使用的是类似于原生开发中 block 的方式进行的.
    父控件通过传入一个方法作为属性,并实现该方法,子控件调用该方法并传入参数,由父控件实现该方法.(这不就是 block 嘛)
    在 React 中通常由父子控件使用该方式传值,且由子控件传递给父控件,所以该方式被称之为 状态提升.
    语法:
    父控件:
    class 父控件 extends React.Component {
    constructor(props) {
    super(props);
    this.block1 = this.block1.bind(this);
    this.block2 = this.block2.bind(this);
    this.state = {属性: '' "};
    }

    block1(参数名) {
    this.setState({属性:参数名});
    }

    block2(参数名) {
    this.setState({属性:参数名});
    }

    render() {
    return (


    <子控件
    参数={this.state.属性}
    block={this.block1} />

        <子控件
          参数={this.state.属性}
          onTemperatureChange={this.block2} />
    
      
    );

    }
    }

    子控件:
    class 子控件 extends React.Component {
    constructor(props) {
    super(props);
    this.事件回调 = this.事件回调.bind(this);
    }

    事件回调(event) {
    this.props.block(event.target.value);
    }

    render() {
    return (


    onChange={this.事件回调} />

    );
    }
    }

    *在需要外传参数时,子控件不能使用自己的 this.state,而是需要调用 this.block(参数)

    组合
    包含关系
    在组件中使用一个名为"children"的数组来将子组件传递到子组件中 代码如下:
    function 子组件(props) {
    return (


    {props.children}

    );
    }
    *这个传递是隐式的,但是当你在组件的内容中写了代码而未在rander 中调用 props.children 时,这些代码是无效的,其未执行 rander 故无法被渲染

    继承
    继承的关键字是 extend,在实际开发时通常通过组合来实现组件的复用,并不需要使用继承

    React 总结
    从移动端开发的角度来看,React类似于使用代码构建界面中的 view,但是要意识到,相比于移动端开发而言,前端是基于界面的,而移动端是基于代码的,移动端的一切界面都可以通过代码调用API 来实现,而前端的 js 是无法做到这一点的,还需要 html 和 css 的配合,React 仅仅是适用于 js 的框架,而开发时还需要 css 的配合才能构建起美观的界面.

    React 最重要的特点就是组件,通过组件的组合可以构建各种不同的视图效果,也让代码更加容易被复用.

    JSX 仅仅是使用 React 的语法扩展.其最大特点是可以在大括号内书写表达式.

    你可能感兴趣的:(React 学习笔记)