React + Umi + TS 快速上手

162 阅读2分钟

不同于Vue.js开箱即用的特点。React提供了丰富的库给开发者使用。本篇记录实战中快速上手React的学习和理解。

tsx文件的结构

import React from 'react';

interface MyComponentProps {
  title: string;
  onClick: () => void;
}

const MyComponent: React.FC<MyComponentProps> = ({ title, onClick }) => {
  return (
    <div onClick={onClick}>
      {title}
    </div>
  );
};

export default MyComponent;

样式的使用方法

  1. 全局样式:写入src/global.less后,umi会自动引入到项目入口文件,在tsx直接使用。
image.png
  1. 本组件样式:写入同目录下的index.less,在tsx进行导入。
// index.less
.container > * {
}

@media screen and (max-width: @screen-xs) {
  .container {
    width: 100% !important;
  }
}

// index.tsx
// 局部样式导入
import styles from './index.less';
const MyComponent: React.FC<MyComponentProps> = ({ title, onClick }) => {
  return (
    <div class = "styles.container">
        // 全局'headerOnRight'类名。直接使用
        <div class = "headerOnRight" onClick={onClick}>
          {title}
        </div>
    <div>
  );
};

路由配置

Umi中,是自动从config/route中读取路由配置的,baseURL写在config/config.ts中。

ReactDom

ReactDOM.render()负责将React的虚拟表示转换为真正的JavaScript语法

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import App from './App';

// 获取页面中的根节点元素 
const rootElement = document.getElementById('root'); 

// 使用ReactDOM.render()将App组件挂载到根节点 
ReactDOM.render(<App />, rootElement);

// 或者
ReactDOM.createRoot(rootElement)
root.render(<App />, rootElement);

React组件

class组件和函数组件

function App(){
    function FnHello {
        return ‹div›hello‹/div>
    }
    class ClassHello extends React.Component {
        constructor(props){
            super(props)
        }
        render () {
            return ‹div›hello class‹/div>
        }
    }
    return {
       <div className="App"›
            <FnHello>‹/FnHello>
            ‹ClassHello›‹/ClassHello› 
        </div>
    }
}

jsx

jsx可以方便地将html写入js中。非jsx时,也可以调用React方法,创建React Element对象,达到相同的效果:

function App(){
    function FnHello {
        return React.createElement('div', [], 'hello')
    }
    class ClassHello extends React.Component {
        constructor(props){
            super(props)
        }
        render () {
            return ‹div›hello class‹/div>
        }
    }
    let com1 = <FnHello>‹/FnHello>
    return {
       <div className="App"›
            <FnHello>‹/FnHello>
            ‹ClassHello›‹/ClassHello› 
            { com1 }
        </div>
    }
}

💡当我们为创建React Element对象的方法命名时,将方法首字母大写,以便与其他对象区分

不同类型渲染方式

  • 字符串、数字:直接渲染
  • 对象:只能渲染element对象
  • 方法:无法渲染
  • 数组:数组每一项单独渲染
  • 表达式:运行表达式
  • 布尔值、undefined、null:不渲染任何内容

事件绑定

🫱 规则:on + 大写首字母事件名

class App extends React.Component {
    f1() {
        console.log(this);
    }

    render() {
        return <div onClick={this.f1.bind(this)}>Click me</div>;
    }
}

💡如果不作绑定,this值为undefined,这是因为在JavaScript中,函数的this指向是由函数是如何被调用的决定的,而不是在哪里被定义的。当你在类中定义一个方法,比如f1,并且你将它作为一个回调函数传递给事件处理器(如onClick),这个方法就会失去其原本的上下文(即类的实例)。

响应式数据

不同于Vue的依赖收集方法,React调用this.setState方法来更新

class App extends React.Component {
    state = {
        a : 0,
    }
    addA = () => {
        this.state.a += 1
        this.setState({
            
        })
    }

    render() {
        return <div>
            {this.state.a}
            <button onClick={this.addA}></button>
         </div>;
    }
}

props值

对比Vue使用插槽的方式,React父组件能给子组件传递任何属性。

class ClassHello extends React.Component {
    // 子组件的props值
    constructor(props){
        super(props)
    }

    state = {
    }
    
    
    render () {
        // 或者ES7新写法
        console.log(this.props)
        return ‹div›hello class‹/div>
    }
}