1 Star 0 Fork 0

BingCola/react-travel

Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
contribute
Sync branch
BingCola add 3822ee9 3 years ago
Cancel
Notice: Creating folder will generate an empty file .keep, because not support in Git
Loading...
README

React

初始化项目

  1. npx create-react-app react-travel --template typescript
  2. cd react-travel
  3. npm run start

CSS 模块化 - CSS in JS

typescript css

  1. 安装插件:yarn add typescript-plugin-css-modules --save-dev

  2. tsconfig.json中配置插件:"compilerOptions":{ "plugins": [ { "name": "typescript-plugin-css-modules" } ] }

  3. vscode配置:创建.vscode/settings.json :

    {
        "typescript.tsdk": "node_modules/typescript/lib",
        "typescript.enablePromptUseWorkspaceTsdk": true
    }
    

css需要作为模块被引入组件

  1. 将App.css重命名为:App.module.css

    /* App.module.css */
    .center {
        text-align: center;
    }
    
    .list {
        line-height: 30px;
        font-size: 20px;
    }
    
  2. 定义声明文件custom.d.ts: 对css引用对象的支持,否则.tsx会报错

    // custom.d.ts
    declare module '*.css' {
        const css: { [key: string]: sting };
        export default css;
    }
    
  3. 组件中使用:

    // App.tsx
    import styles from './App.module.css'; 
    
    function App() {
        return (
            <div className={styles.center}>
                <div className={styles.list}>
                    CSS in JS
                </div >
            </div>
        );
    }
    
    export default App;
    

使用 Ant Design

官网:https://ant.design/index-cn

  1. 安装UI组件库:yarn add antd

  2. 安装Icon图标:yarn add @ant-design/icons --save

  3. index.tsx中引入css:import 'antd/dist/antd.css';

  4. 组件中使用UI:

    import { Input } from 'antd';
    
    <Input.Search placeholder='请输入关键字' />
    
  5. 组件中使用Icon:

     import { MessageOutlined } from '@ant-design/icons';
    
     <MessageOutlined style={{ fontSize: '16px', color: '#08c' }} />;
    

路由

安装路由

  1. 安装:yarn add react-router-dom --save-dev
  2. 会自动安装react-router核心框架
  3. 安装typescript的声明文件:npm install @types/react-router-dom --save-dev

使用路由

  1. BrowserRouter:路由导航与原生浏览器操作行为一致
  2. Route:路由的路径解析原理与原生浏览器一致,可以自动识别url路径
  3. Switch:路径的切换以页面为单位,不要页面堆叠

基础路由eg:

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import { Home } from './pages'

function App() {
    return (
        <div>
            <BrowserRouter>
                {/* Switch 解决页面叠加问题,每次只渲染一个路由页面 */}
                <Switch>
                    <Route path="/" component={Home} exact />
                    <Route path="/signIn" render={(() => <h1>登录页面</h1>)} />
                    <Route render={(() => <h1>404 not found 页面</h1>)} />
                </Switch>
            </BrowserRouter>
        </div >
    );
}

export default App;

路由中参数传递

使用分段路由Segments:http://localhost:3000/products/11121314

1. App.tsx中添加详情页的路由

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import { Home, Detail } from './pages'

function App() {
    return (
        <div className={styles.App}>
            <BrowserRouter>
                <Switch>
                    <Route path="/" component={Home} exact />
                    <Route path="/detail/:id" component={Detail} /> {/* 路由添加参数id */}
                </Switch>
            </BrowserRouter>
        </div >
    );
}

export default App;

2. Home.tsx中跳转到详情页的路由

  1. 使用高阶函数:

    import React from "react";
    import { withRouter } from "react-router-dom"; // 高阶函数
    
    const HomeComponent: React.FC = ({ history, location, match }) => {
        console.log(history, location, match);
        return (
            <div onClick={() => history.push(`detail/123456`)}>
                跳转至详情页,并传递参数id
            </div>
        );
    }
    
    export const Home = withRouter(HomeComponent); // 使用高阶函数封装路由
    
  2. 使用hook:

    import React from 'react';
    import { useHistory, useLocation, useParams, useRouteMatch } from 'react-router-dom'; // hook
    
    export const Home: React.FC = () => {
    
        // 使用hook
        const history = useHistory();
        const location = useLocation();
        const params = useParams();
        const match = useRouteMatch();
    
        return (
            <div onClick={() => history.push(`detail/123456`)}>
                跳转至详情页,并传递参数id
            </div>
        );
    };
    
  3. 使用Link:

    import React from "react";
    import { Link } from "react-router-dom"; // link
    
    export const Home: React.FC = () => {
        return (
            <Link to={`detail/123456`}>
                跳转至详情页,并传递参数id
            </Link>
        );
    }
    

3. Detail.tsx详情页中获取参数

import React from 'react';

export const Detail: React.FC<any> = (props) => {
    console.log(props.match.params.id);
}

国际化(I18n)

安装

npm install react-i18next i18next --saveyarn add react-i18next i18next --save

配置

新建文件夹i18n\config.ts:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import translation_en from './en.json'; // 配置的英文json
import translation_zh from './zh.json'; // 配置的中文json

const resources = {
    en: {
        translation: translation_en,
    },
    zh: {
        translation: translation_zh,
    },
};

i18n.use(initReactI18next).init({
    resources,
    lng: 'zh',
    interpolation: {
        escapeValue: false,
    },
});

export default i18n;

使用

  1. index.tsx中引入:import './i18n/config'

  2. 组件中Home.tsx:

    import React from 'react';
    import { useTranslation } from 'react-i18next'
    
    export const Home: React.FC = () => {
        const { t } = useTranslation()
        return (
            <div> 
                {t('home.detail')}
            </div>
        );
    };
    
    
  3. 点击按钮切换,reducer.ts中:

    import i18n from 'i18next';
    
    export interface languageState {
        language: 'zh' | 'en';
        languageList: { name: string; code: string }[];
    }
    
    const defaultState: languageState = {
        language: 'zh',
        languageList: [
            { name: '中文', code: 'zh' },
            { name: 'English', code: 'en' },
        ],
    };
    
    const reducer = (state = defaultState, action) => {
        switch (action.type) {
            case 'change_language':
                i18n.changeLanguage(action.value);
                return { ...state, language: action.value };
            default:
                return state;
        }
    };
    
    export default reducer;
    
    

React的核心思想就是组件化,组件化带来最大好处就是组件彼此独立,可以复用。

什么是钩子(hooks)

  1. 消息处理的一种方法,用来监视指定程序
  2. 函数组件中需要处理副作用,可以用钩子把外部代码“钩”进来
  3. 常用钩子:useState,useEffect,useContext,useReducer
  4. hooks一律使用use前缀命名:useXxx

副作用

纯函数:给一个函数同样的参数,那么这个函数永远返回同样的值。

副作用与穿函数相反,指一个函数处理了与返回值无关的事情。 输入参数一样,而输出结果不确定的情况就是副作用。 纯函数中没有副作用,有副作用的不是纯函数。

React中的副作用有:state状态的改变、生命周期、构建函数... 函数式组件中使用useEffect处理副作用

  1. useEffect的第二个参数为一个非空数组时,会在count值发生变化时调用(相当于vue中的watch)

    useEffect(() => {
        document.title = `You clicked ${count} times`; // 监听count值变化
    }, [count])
    
  2. useEffect的第二个参数为一个空数组时,初始化调用一次之后不再执行(相当于componentDidMount)

    useEffect(() => {
        console.log('hello world'); // 仅在初始化时调用一次
    }, [])
    
    // 等价于
    
    componentDidMount() {
        console.log('hello world');
    }
    
  3. useEffect没有第二个参数时,组件的初始化和更新都会执行,(相当于componentDidMount + componentDidUpdate),容易死循环(夺命连环call)

    useEffect(() => {
        document.title = `You clicked ${count} times`;
    });
    
    // 等价于
    
    componentDidMount() {
        document.title = `You clicked ${this.state.count} times`;
    }
    
    componentDidUpdate() {
        document.title = `You clicked ${this.state.count} times`;
    }
    
  4. useEffect返回一个函数时,这个函数会在组件卸载时执行(相当于componentDidMount+componentWillUnmount)

    useEffect(() => {
        const id = setInterval(() => {
            setCount(c => c + 1);
        }, 1000);
        return () => clearInterval(id); // 相当于componentWillUnmount
    }, []);
    
    // 等价于
    
    componentDidMount() {
        this.id = setInterval(() => {
            this.setState({count: this.state.count + 1})
        }, 1000);
    }
    
    componentWillUnmount() {
        clearInterval(this.id);
    }
    

高阶组件(HOC)

  1. 高阶组件(HOC)就是一个返回了组件的函数
  2. 通过组件嵌套的方法给子组件添加更多的功能
  3. 接收一个组件作为参数并返回一个经过改造的新组件

简而言之,高阶组件是参数为组件,返回值为新组件的函数。 const hoc = higherOrde(wrappedComponent)

组件是将 props 转换为 UI,而高阶组件是将组件转换为另一个组件。

高阶组件优点

  1. 抽取重复代码,实现组件复用
  2. 条件渲染,控制组件的渲染逻辑(渲染劫持)
  3. 捕获/劫持被处理组件的生命周期
import React from 'react';

const withAddToCart = (ChildComponent)=>{
    return (props) =>{
        return <ChildComponent {...props}>
    }
}

React-Redux

https://react-redux.js.org/

1.安装

npm install react-redux @types/react-redux yarn add react-redux @types/react-redux

2.引入Provider

index.tsx中引入Provider:

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

import { Provider } from 'react-redux'; // 引入Provider
import store from './redux/store'; // 引入store

ReactDOM.render(
    <React.StrictMode>
        {/* 使用Provider并加载数据仓库 */}
        <Provider store={store}> 
            <App />
        </Provider>
    </React.StrictMode>,
    document.getElementById('root')
);

3.connect()

组件中使用connect().

import { connect } from 'react-redux';
// ...
export const Xxx = connect(mapStateToProps, mapDispatchToProps)(XxxComponents);

Empty file

About

Cancel

Releases

No release

Contributors

All

Language(Optional)

Activities

can not load any more
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/bing-cola/react-travel.git
git@gitee.com:bing-cola/react-travel.git
bing-cola
react-travel
react-travel
master

Search