分类
react

mobx

定义

import { observable } from "mobx";

class Todo {
    id = Math.random();
    @observable title = "";
    @observable finished = false;
}
import { decorate, observable } from "mobx";

class Todo {
    id = Math.random();
    title = "";
    finished = false;
}
decorate(Todo, {
    title: observable,
    finished: observable
})

经过计算的属性

class TodoList {
    @observable todos = [];
    @computed get unfinishedTodoCount() {
        return this.todos.filter(todo => !todo.finished).length;
    }
}
分类
react

react-router-dom

最基本的路由

  • 在Route中加入exact确保精准匹配,用在主页面
  • 在Route下放置组件
import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";

export default function BasicExample() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/dashboard">Dashboard</Link>
          </li>
        </ul>

        <hr />
        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/dashboard">
            <Dashboard />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

// You can think of these components as "pages"
// in your app.

function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}

function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
    </div>
  );
}

如何使用路由参数

  • 首先引入Router包在外面(import { Router } from ‘react-router-dom’)
  • 引入跳转功能放在Router里面(import { Link } from ‘react-router-dom’)
  • 引入Switch加上切换页面的功能(import { Switch } from ‘react-router-dom’)
  • 引入Route,switch的子节点。(import { Route } from ‘react-router-dom’)
  • 在Route中定义路由参数和children
  • children的函数式组件可以使用useParams()获取路由参数对象
import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useParams
} from "react-router-dom";

export default function ParamsExample() {
  return (
    <Router>
      <div>
        <h2>Accounts</h2>

        <ul>
          <li>
            <Link to="/netflix">Netflix</Link>
          </li>
          <li>
            <Link to="/zillow-group">Zillow Group</Link>
          </li>
          <li>
            <Link to="/yahoo">Yahoo</Link>
          </li>
          <li>
            <Link to="/modus-create">Modus Create</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/:id" children={<Child />} />
        </Switch>
      </div>
    </Router>
  );
}

function Child() {
  // We can use the `useParams` hook here to access
  // the dynamic pieces of the URL.
  let { id } = useParams();

  return (
    <div>
      <h3>ID: {id}</h3>
    </div>
  );
}

嵌套的路由

  • 主要使用了useRouteMatch这个hook,这和匹配Route的原理是一样的
  • 从useRouteMatch从取得path和url,url是真实的跳转路径,path大多数时候和url一样,但是会有/path/:id这样的情况可用在Route里
import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useParams,
  useRouteMatch
} from "react-router-dom";

export default function NestingExample() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/topics">Topics</Link>
          </li>
        </ul>

        <hr />

        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/topics">
            <Topics />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

function Topics() {
  let { path, url } = useRouteMatch();

  return (
    <div>
      <h2>Topics</h2>
      <ul>
        <li>
          <Link to={`${url}/rendering`}>Rendering with React</Link>
        </li>
        <li>
          <Link to={`${url}/components`}>Components</Link>
        </li>
        <li>
          <Link to={`${url}/props-v-state`}>Props v. State</Link>
        </li>
      </ul>

      <Switch>
        <Route exact path={path}>
          <h3>Please select a topic.</h3>
        </Route>
        <Route path={`${path}/:topicId`}>
          <Topic />
        </Route>
      </Switch>
    </div>
  );
}

function Topic() {
  let { topicId } = useParams();

  return (
    <div>
      <h3>{topicId}</h3>
    </div>
  );
}

有权限的路由

  • 在Link中我们有一个需要权限的路由跳转
  • 该需要权限的路由是获取useContext里的数据表示用户是否有权限
  • 有权限把children渲染进去,无权限重定向至/login

https://reactrouter.com/web/example/auth-workflow

匹配的路由给与修改

  • 不直接定义Link,给Link套一层
  • 在Link外层加入参数
  • 在函数内使用useRouterMatch(带参数)去匹配路由,如果匹配上添加一点样式

https://reactrouter.com/web/example/custom-link

当表单里有内容阻止页面离开

  • 需要一个数据来知道表单是否被修改过
  • 使用Prompt组件阻止离开

https://reactrouter.com/web/example/preventing-transitions

不匹配地址

  • 核心理念就是加入一个匹配任何页面的Route
  • 定义Route下的函数
  • 可以使用useLocation获取到想要到达的地址

https://reactrouter.com/web/example/no-match