美文网首页
react-02-基础和组件

react-02-基础和组件

作者: 未来在奋斗 | 来源:发表于2019-12-16 13:56 被阅读0次

React介绍

React 是一个用于构建用户界面的 JAVASCRIPT 库。

React 主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。

React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。

搭建React开发环境

安装 create-react-app 命令 (基于 webpack + es6)

npm install -g create-react-app

使用 create-react-app 创建一个名字叫做 my-app 的项目

create-react-app my-app

如果创建项目过程中,提示node版本低,不兼容,那么执行 yarn config set ignore-engines true 解决该问题。

进入 my-app 目录

cd my-app/

启动

npm start
# or
yarn start

yarn 的安装方法:npm i -g yarn

yarn config set registry https://registry.npm.taobao.org -g

yarn config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/ -g

虚拟DOM与DIFF算法(重点)

虚拟DOM(Virtual dom),也就是我们常说的虚拟节点,它是通过JS的Object对象模拟DOM中的节点,然后再通过特定的render方法将其渲染成真实的DOM的节点。

// 创建虚拟节点
var temp = document.createDocumentFragment();

for( var i=0; i<100; i++ ){
    var li = document.createElement('li');
    // 将li放入虚拟节点中,这一步操作不会产生重绘回流
    temp.appendChild(li);
    li.innerHTML = i;
}

// 真实节点的操作
ul1.appendChild(temp);

为什么要使用虚拟节点?

频繁的操作DOM,会大量的造成页面的重绘和回流,出于性能优化的考虑,我们应该减少重绘和回流的操作。

重绘:例如 div1.style.color='red' 这种代码,只能改变颜色,并不会影响其他元素的布局,这种操作被称为重绘。

回流:例如 div1.style.padding = '20px' 这种代码,会影响到其他元素的布局,这种操作被称为回流。

回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流。

对虚拟节点的DOM操作,并不会触发重绘和回流,把处理后的虚拟节点映射到真实DOM上,只触发一次重绘和回流。

DIFF算法

DIFF算法是DOM更新的一种算法,指页面被更新时,程序用哪种策略去做更新DOM。

JSX语法(重点)

React 使用 JSX 来替代常规的 JavaScript。

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

JSX防止了XSS攻击,如果想渲染成元素,使用

<div dangerouslySetInnerHTML={{__html:abc}}></div>
  • html标签部分允许嵌套,但顶层仅允许有1个标签。(可以用<></>解决多节点问题)
  • 可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。
  • JSX 中不能使用 if else 语句,但可以使用三元运算。
  • React 推荐使用内联样式。
var myStyle = { fontSize: 100, color: '#FF0000'};
ReactDOM.render(
    <h1 style = {myStyle}>hello world</h1>,
    document.getElementById('example')
); 

注释:需要写在花括号中

ReactDOM.render(
    <div><h1>hello world</h1>{/*注释...*/}</div>,
    document.getElementById('example')
);

数组:JSX 允许在模板中插入数组,数组会自动展开所有成员

var arr = [ <h1>你好</h1>, <h2>react</h2>,];
ReactDOM.render(
    <div>{arr}</div>,
    document.getElementById('example')
);

Fragments

class Columns extends Component {   
    render(){
        return <>
            <td>Hello</td>
            <td>World</td>
        </>;
    }
}

class App extends Component {   
    render(){
        return (            
            <table>
                <tbody>
                    <tr>
                        <td>react</td>
                        <Columns />
                    </tr>
                </tbody>
            </table>
        );
    }
}

无状态组件(影子组件)

优势是创建组件所消耗的资源最少,通常只用于渲染一些普通的html内容。

function Comp1(props){
    return <div></div>
}

有属性,但没有状态,也没有this

Class类组件(重点)

创建及使用组件

class App extends React.Component {
    render() {
        return <h1>Hello World!</h1>;
    }
}
ReactDOM.render(
    <App />, 
    document.getElementById('example')
);

State状态(重点)

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。

React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

class Clock extends React.Component {
    constructor(props) {
        super(props);
        this.state = { date: new Date() };
    }
    render() {
        return (
            <div>
                <h2>现在是 { this.state.date.toLocaleTimeString() }</h2>
            </div>
        );
    }
    // 在组件输出到 DOM 后,会执行 componentDidMount() 钩子。
    componentDidMount() {
        this.timerID = setInterval(
            ()=>this.tick(), 1000    
        );
    }
    // 组件被从 DOM 中移除,React 会调用 componentWillUnmount()钩子。
    componentWillUnmount() {
        clearInterval( this.timerID );
    }
    tick() {
        // 设置状态,只要state发生变化,render就会自动重新渲染。
        this.setState({ date: new Date() });
    }
}
ReactDOM.render( <Clock />, document.getElementById('example') );

条件渲染(重点)

可以根据应用的状态变化只渲染其中的一部分。

class User extends React.Component {
    render() {
        var isLogin = this.props.isLogin;
        if (isLogin) {
            return <Success />;
        }else{
            return <Register />;
        }
    }
}
ReactDOM.render( <User isLogin={true} />, document.getElementById('root'));

列表循环(重点)

列表和渲染:

render(){
    var lis = [<li>a</li>, <li>b</li>];
    return (<ul>{lis}</ul>);
}

上面的代码,是能够在ul中显示两个li的,但是console中会报错。“每一项都要有key”

解决方案:

var lis = ["a", "b", "c"].map((val, ind)=><li key={ind}>{val}</li>)

Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。

因此你应当给数组中的每一个元素赋予一个确定的标识。

  • key在兄弟元素中必须唯一,但并非全局唯一,即在不同组件中,key可以相同。
  • key 会作为给 React 的提示,但不会传递给你的组件。如果您的组件中需要使用和 key 相同的值,请将其作为属性传递

复合组件

子组件

class Welcome extends React.Component {
    render() {
        return (<div>子组件</div>);
    }
}
export default Welcome;

父组件使用

import Welcome from './Welcome.js'
class App extends React.Component {
    render() {
        return (<div>
            父组件 <Welcome></Welcome>
        </div>);
    }
}

Props属性(重点)

参数 props

class Welcome extends React.Component {
    render() {
        return <h1 className={this.props.className}>Hello World</h1>;
    }
}
ReactDOM.render(
    <Welcome className="abc" />,
    document.getElementById('example')
);

默认属性 defaultProps

class Welcome extends React.Component {
    render() {
        return <h1>{this.props.name}</h1>;
    }
}
Welcome.defaultProps = {
    name: '默认值'
};
ReactDOM.render(
    <Welcome name="张三" />,
    div
);

绑定事件(重点)

绑定事件时,onClick的C必须大写。

class Welcome extends React.Component {
    sum(a, b){
        alert('sum:'+(a+b));
    }
    render() {  
        return (
            <div>
                <button onClick={()=>{this.sum(1,2)}}>按钮</button>
            </div>
        );
    }
}
ReactDOM.render( <Welcome />, div );

注意 sum 函数触发时的 this 指向

class Welcome extends React.Component {
    sum(a, b){
        alert('sum:'+(a+b));
    }
    render(){
        return (
            <div>
                <button onClick={this.sum.bind(this,1,2)}>按钮</button>
            </div>
        );
    }
}
ReactDOM.render( <Welcome />, div );

React.createClass 创建组件

const Comp2 =React.createClass({
    mixins: [MixinA],
    render(){
        return <div>ES5组件的创建方法,已经被废除了,使用会报错。</div>
    }
})

受控组件与非受控组件

受控组件说的是该表单元素的值与react的模型层已经绑定在一起了。

class App extends React.Component{
    constructor(){
        super();
        this.state = {
            val : 'hello'
        }
    }
    fn(e){
        var newVal = e.target.value;
        this.setState({
            val: newVal
        })
    }
    fn2(){
        this.setState({
            val: 'hahaha'
        })
    }
    render(){
        return (
            <div>
                <input type="text" value={this.state.val} onChange={e=>{this.fn(e)}} />
                {this.state.val}
                <button onClick={()=>this.fn2()}>修改</button>
            </div>
        );
    }    
}

如果有 value ,就必须写 onChange

非受控组件说的是视图层与模型层没有关联

class App extends React.Component{
    constructor(){
        super();
        this.state = {
            val : 'hello'
        }
    }
    fn(){
       alert( this.refs.abc.value ) 
    }
    render(){
        return (
            <div>
                <input type="text" defaultValue={this.state.val} ref="abc" />
                {this.state.val}
                <button onClick={()=>this.fn()}>获取</button>
            </div>
        );
    }    
}

Ref 对元素或子组件进行标记

ref 可以对元素或组件进行标记。

class Comp2 extends React.Component{
    constructor(){
        super();
        this.state = {
            b: 1
        }
    }
    render(){
        return <div>abc-{this.props.a}-{this.state.b}</div>
    }
}

class App extends React.Component{
    constructor(){
        super();
        this.state = {
            a : 0
        }
    }
    fn(){
        this.setState(state=>({
           a : state.a+1
        }))
        this.refs.abc.state.b = 3;
    }
    render(){
        return (
            <div>
                <Comp2 ref="abc" a={this.state.a} />
                <button onClick={()=>this.fn()}>设置</button>
            </div>
        );
    }    
}

相关文章

  • Angular组件篇

    Angular组件 一:组件基础 1:什么是组件? 组件(Component)是构成Angular应用的基础和核心...

  • 组件化之路—集成组件SDK

    介绍 组件化的前提是要有基础组件、功能组件、业务组件这三大块。其中基础组件和功能组件都可以做成SDK,可以供其他A...

  • 组件化和模块化

    对组件化我的理解。 1、组件化和模块化的特定与区别 组件重用、解耦高重用、松耦合无统一接口基础库、基础组件纵向分层...

  • 第七章 RabbitMQ基础架构设计思路

    课程导航 一线大厂的MQ组件实现思路和架构设计方案 基础组件封装设计 - 迅速消息发送 基础组件封装设计 - 确认...

  • 组件化流程

    组件化创建大致步骤,以项目、基础组件为例 1、创建项目、基础组件远程仓库 创建项目远程仓库,基础组件远程仓库如下 ...

  • DataPicker

    Android基础:Date & Time组件(上)Android基础:Date & Time组件(下)

  • vue命名规范

    自用vue变量命名规范 props 驼峰式命名 事件 组件 组件文件 基础组件名 基础组件名 name Pasca...

  • React个人整理

    React基础 自定义新组件 props和propTypes 带状态的文本框组件 从外部访问组件(谨慎使用) 中途...

  • 分布式应用系统架构设计与实践之基础组件(二)

    3 常见的基础组件 四个基础组件 数据缓存:数据进行缓存,提高数据获取性能 数据分发:数据中转和消息通知机制,实现...

  • 应用程序UI编程

    基础组件 基础内容组件 表单组件 微信小程序伸缩布局 视图容器 view scroll-viewswiper-view

网友评论

      本文标题:react-02-基础和组件

      本文链接:https://www.haomeiwen.com/subject/jrpsnctx.html